home *** CD-ROM | disk | FTP | other *** search
- .XLIST
- ;******************** Version 1.20 *********************************
- ; [20] (a) When in terminal emulation, if host sends an ESC-Z to
- ; identify the terminal type being used, respond with "ESC / K".
- ; (b) Allow ^X/^Z to interrupt sending a file or file group,
- ; respectively. (c) Ditto to interrupt receiving a file or file
- ; group. (d) If get an error when receiving a file, clean up
- ; and send an error packet. Allow user to specify whether to
- ; keep what made it over or to discard it. (e) Before sending a
- ; packet, clear the input buffer. (f) Use one general routine
- ; to send all error packets. (g) Add U. of Arizona changes so
- ; Kermit once again compiles on the Z100 (Joellen Windsor). Move
- ; IBM specific statements inside IBM conditional assembly blocks.
- ; Daphne, 11/28/83
- ;******************** Version 1.19A *********************************
- ; [19] (a) Change NOUT to print numbers in decimal instead of hex.
- ; Routine is based on the one used in Generic Kermit. Make a
- ; cosmetic change where print filenames & remove extraneous screen
- ; output. Add "nop" in NAK because the jump to ABORT is only
- ; 2 bytes. Change ONTAB so the valid values are in alphabetical
- ; order. Also, keep only one copy of the code that sets the baud
- ; rate and prints it's value. (b) Allow users to choose between
- ; COM1 (default) and COM2. Also, remind the user about which
- ; communications port they are using and at what baud rate when
- ; connecting to another system. (c) Add SET BACKARROW so can
- ; set backarrow to backspace or delete. (William Dair) Also,
- ; set default to ON for renaming files due to filename conflicts.
- ; (d) When connecting to host, only bump up cursor if on line 25.
- ; (e) Clean up parsing error messages. Change VT52 emulation
- ; messages to Heath-19.
- ; Daphne, 10/21/83
- ;******************** Version 1.18 **********************************
- ; [18] A NAK for the next packet is not the same as an ACK for the
- ; current packet if we're in Send-Init. Also, account for
- ; wraparound when comparing packet numbers that are off by one.
- ; Daphne, 7/13/83
- ;******************** Version 1.3A **********************************
- ; [17] (a) Make command to SET BELL ON/OFF when transfer is complete.
- ; Changed variable name to be consistent with other flags.
- ; (b) Make it more like a Heath/Zenith H19 (I/D L/C,inverse,24x80).
- ; (c) Fix Telflg to be in CS so Telnet works.
- ; Dave King (CMU), 7/1/83
- ;******************** Version 1.3 **********************************
- ; [16] Make adjustments to XT changes so that things that used to work
- ; still do: pass along characters with the eighth bit on, and in
- ; OUTCHR, don't overwrite character after setting the appropriate
- ; parity.
- ; Daphne, 6/17/83
- ; [15] Add tabs stop and clear screen support. Don't give checksum
- ; warnings. Give keyboard input higher scheduling priority than
- ; port input. This allows users to ^S, ^O, ^C, etc. the output
- ; when the port is full of characters. Add a CMU conditional
- ; to swap control-backspace (delete) with backspace since TOPS-20
- ; and VMS are more delete than backspace oriented.
- ; Glenn Marcy, 6/8/83
- ; [14] Add CMU changes that allow Kermit to work on the XT. Plus add
- ; a statement omitted previously when comparing packet numbers.
- ; Daphne, 5/26/83 (changes by Dave King, CMU)
- ;******************** Version 1.2 **********************************
- ; [13] When closing received file, handle case where number of bytes is
- ; divisible by 128.
- ; Daphne, 5/2/83
- ;******************** Version 1.1 **********************************
- ; [12] If "SET IBM", set local echo, XON/XOFF, and default (mark) parity.
- ; Daphne, 4/15/83
- ; [11] In RPACK, don't push packet type, but store in temp variable.
- ; If push and get an error, you pick up packet type as return addr.
- ; Daphne, 4/15/83
- ; [10] Add Set Parity Command.
- ; Daphne, 4/12/83
- ; [9] Allow single-character wildcard in filenames, use "=".
- ; Daphne, 4/4/83
- ; [8] Add Kermit server support.
- ; Daphne, 3/17/83
- ; [7] Allow wildcards in filename.
- ; Daphne, 3/15/83
- ; [6] Make format of "Set Escape" look like the other commands.
- ; Daphne, 3/14/83
- ; [5] Add Set "End-of-Line" (to the char used to terminate packets I send).
- ; Daphne, 3/7/83
- ; [4] Ring bell when done (when succeed and when fail).
- ; Daphne, 2/10/83
- ; [3] Match keyword if "?" is the terminator.
- ; Daphne, 2/9/83
- ; [2] Change "Inpkt" so ignores bare CR from any system.
- ; Daphne, 2/9/83
- ; [1] Add "cmer04" - print error message if run off list of commands allowed.
- ; Daphne, 2/9/83
-
- ;******************** Version 1.0 **********************************
- ; KERMIT - KL10 Error-free Reciprocal Micro Interconnect over TTY-lines
- ;
- ; Program Version 1.20, Kermit Protocol Version 2
- ; November 4, 1983
- ;
- ; Based on the KERMIT Protocol.
- ;
- ; Copyright (C) 1982,1983 Trustees of Columbia University
- ;
- ; Daphne Tzoar
- ; Columbia University Computer Center
- ; 612 W. 115th St.
- ; New York City, NY 10025
- ;
- ; Special thanks to Frank da Cruz, Bill Catchings, Steve Jensen,
- ; Vace Kundakci, and Bernie Eiben for their help and contributions.
-
-
- ; This file is the global data area for all the Kermit modules.
-
-
- CMU EQU 0 ; CMU conditional assembly. [15]
- IBMPC EQU 1 ; For IBM PC conditional assembly.
- Z100 EQU 0 ; For Heath/Zenith Z-100.
- STEVE EQU 0 ; For Steve's homebrew assembly.
-
- BELL EQU 07Q
- TAB EQU 11Q
- LF EQU 12Q
- FF EQU 14Q
- CR EQU 15Q
- XON EQU 21Q
- XOFF EQU 23Q
- ESC EQU 33Q
- DEL EQU 177Q
- BS EQU 08H
-
- DOS EQU 21H
-
- CONIN EQU 01H
- CONOUT EQU 02H
- RDRIN EQU 03H
- PUNOUT EQU 04H
- LSTOUT EQU 05H
- DCONIO EQU 06H
- GTIOB EQU 07H
- PRSTR EQU 09H
- CONSTAT EQU 0BH
- OPENF EQU 0FH
- CLOSF EQU 10H
- SFIRST EQU 11H
- SNEXT EQU 12H
- DELF EQU 13H
- READF EQU 14H ; Read from the file.
- WRITEF EQU 15H
- MAKEF EQU 16H
- SETDMA EQU 1AH
- CFLSZ EQU 23H
-
- MAXPKT EQU '~'-' '+2Q ; Maximum size of a packet.
- MAXTRY EQU 05Q ; Default number of retries on a packet.
- IMXTRY EQU 20Q ; Default number of retries send initiate.
- DRPSIZ EQU 5EH ; Default receive packet size.
- DSPSIZ EQU 20H ; Default send packet size.
- DSTIME EQU 08H ; Default send time out interval.
- DRTIME EQU 05H ; Default receive time out interval.
- DSPAD EQU 00H ; Default send padding.
- DRPAD EQU 00H ; Default receive padding.
- DSPADC EQU 00H ; Default send padding char.
- DRPADC EQU 00H ; Default receive padding char.
- DSEOL EQU CR ; Default send EOL char.
- DREOL EQU CR ; Default receive EOL char.
- DSQUOT EQU '#' ; Default send quote char.
- DRQUOT EQU '#' ; Default receive quote char.
-
- PAREVN EQU 00H ; Even parity. [10 start]
- PARMRK EQU 01H ; Mark parity.
- PARNON EQU 02H ; No parity.
- PARODD EQU 03H ; Odd parity.
- PARSPC EQU 04H ; Space parity.
- DEFPAR EQU PARNON ; Default parity (none.)
- IBMPAR EQU PARMRK ; IBM's parity (mark.) [10 end]
-
- SOH EQU 01H ; Start of header char.
- BUFSIZ EQU 80H ; Size of DMA.
- DIASW EQU 01H ; Default is diagnostics on.
-
- CMKEY EQU 01H ; Parse a keyword.
- CMIFI EQU 02H ; Parse an input file spec (can be wild).
- CMOFI EQU 03H ; Parse an output file spec.
- CMCFM EQU 04H ; Parse a confirm.
- CMTXT EQU 05H ; Parse arbitrary text up to CR. [8]
-
- IF ibmpc
- BIOS EQU 10H
- COMM EQU 14H
- KEYB EQU 16H
- DEFESC EQU ']'-100Q ; The default escape character.
- MDMDAT1 EQU 03F8H ; Address of modem port (data). [19b]
- MDMSTS1 EQU 03FDH ; Address of modem port status. [19b]
- MDMCOM1 EQU 03FBH ; Address of modem port command. [19b]
- MDMDAT2 EQU 02F8H ; Port 2 address. [19b]
- MDMSTS2 EQU 02FDH ; Port 2 status. [19b]
- MDMCOM2 EQU 02FBH ; Port 2 command. [19b]
- MDMINP EQU 1 ; Input ready bit.
- BRKBIT EQU 040H ; Send-break bit. [20g]
- MDMINTV EQU 0030H ; Address of modem port interrupt vector.
- MDINTV2 EQU 002CH ; Address for port 2. [19b]
- MDMINTO EQU 0EFH ; Mask to enable interrupt for modem port.
- MDINTO2 EQU 0F7H ; Enable interrupt level 3. [19b]
- MDMINTC EQU 010H ; Bit to set to disable interrupts for modem.
- MDINTC2 EQU 008H ; Disable IRQ3. [19b]
- INTCONT EQU 0021H ; Address of 8259 interrupt controller ICW2-3.
- INTCON1 EQU 0020H ; Address of 8259 ICW1.
- EOICOM EQU 0064H ; End of interrupt.
- EOICOM2 EQU 0063H ; End of interrupt for COM2. [19b]
- TIMER EQU 40H ; Use to issue short beep.
- PORT_B EQU 61H ; Port B address.
-
- B0300 EQU 180H ; Variables for 300 baud, 1200, etc.
- B1200 EQU 60H
- B1800 EQU 40H
- B2400 EQU 30H
- B4800 EQU 18H
- B9600 EQU 0CH
- ENDIF
-
- IF Z100
- MDMCOM EQU 0EFH ; Asynch port command register. [20g]
- BRKBIT EQU 048H ; Send-break bits. [20g]
- DEFESC EQU '\'-100Q ; The default escape character.
-
- ; BIOS entry points
-
- BIOS_SEG SEGMENT AT 40H ; Define segment where BIOS really is
-
- ORG 6*3
- BIOS_AUXOUT LABEL FAR ; AUX output routine
-
- ORG 26*3
- BIOS_AUXFUNC LABEL FAR ; AUX: function
-
- BIOS_SEG ENDS ; End of BIOS segment defs
-
- ; Function codes for BIOS_AUXFUNC
- CHR_READ EQU 1 ; Read character
- CHR_STATUS EQU 2 ; Get status
- CHR_SFGS EQU 0 ; Get status subfunction
- CHR_SFGC EQU 1 ; Get config subfunction
- CHR_CONTROL EQU 3 ; Control function
- CHR_CFSU EQU 0 ; Set new configuration parameters
-
- B00455 EQU 0 ; 45.5 baud
- B0050 EQU 1 ; 50 baud
- B0075 EQU 2 ; 75 baud
- B0110 EQU 3 ; 110 baud
- B01345 EQU 4 ; 134.5 baud
- B0150 EQU 5 ; 150 baud
- B0300 EQU 6 ; 300 baud
- B0600 EQU 7 ; 600 baud
- B1200 EQU 8 ; 1200 baud
- B1800 EQU 9 ; 1800 baud
- B2000 EQU 10 ; 2000 baud
- B2400 EQU 11 ; 2400 baud
- B4800 EQU 12 ; 4800 baud
- B9600 EQU 13 ; 9600 baud
- B19200 EQU 14 ; 19200 baud
- B38400 EQU 15 ; 38400 baud
- ENDIF
-
- STACK SEGMENT PARA STACK 'STACK'
- DW 100 DUP(0) ; Initialize stack to all zeros.
- STK EQU THIS WORD
- STACK ENDS
-
- DATAS SEGMENT PARA PUBLIC 'DATAS'
-
- ; Pure storage.
-
- versio db 'CUCCA'
- IF ibmpc
- db ' IBM-PC'
- ENDIF
- IF Z100
- db '/Stevens Heath/Zenith Z-100'
- ENDIF
- db ' Kermit-86 - ver 1.20',cr,lf,'$' ;[19a]
- kerm db 'Kermit-86>$'
- spmes db 'Spack: $'
- rpmes db 'Rpack: $'
- hibit db 'Warning - Non Ascii char$'
- tmp db ?
- foo db '$'
- crlf db cr,lf,'$'
- ender db bell,bell,'$' ; [4]
- tmsg1 db cr,lf,'[Connecting to host, type $'
- tmsg3 db ' C to return to PC$' ; [17b, 19b]
- tmsg2 db cr,lf,'[Back at micro]',cr,lf,'$'
- tmsg4 db ', connecting over port COM$' ; [19b]
- ermes1 db cr,lf,'?Unregonized command$'
- ermes2 db cr,lf,'?Illegal character$'
- ermes3 db cr,lf,'?Not confirmed$'
- ermes4 db 'Unable to rename file$'
- ermes7 db '?Unable to receive initiate$'
- ermes8 db '?Unable to receive file name$'
- ermes9 db '?Unable to receive end of file$'
- erms10 db '?Unable to receive data$'
- erms11 db '?Disk full$'
- erms14 db '?Unable to receive an acknowledgement from the host$'
- erms15 db '?Unable to find file$'
- erms17 db 'Record length exceeds size of buffer$'
- erms18 db cr,lf,'?Unable to tell host that session is finished$'
- erms19 db cr,lf,'?Unable to tell host to logout$'
- infms0 db 'Waiting .....$'
- infms1 db 'Receiving ...$'
- infms2 db 'Sending .....$'
- infms3 db 'Completed $'
- infms4 db 'Failed $'
- infms5 db 'Renaming file to $'
- infms6 db 'Interrupted $' ; [20b]
- infms7 db 'File interrupt: OK $' ; [20b]
- infms8 db 'File group interrupt: OK $' ; [20b]
-
- cfrmes db ' Confirm with carriage return $'
- filhlp db ' Input file spec (possibly wild) $'
- esctl db 'Control-$' ; [6]
- spchar db 24H,26H,23H,40H,21H,25H,27H,28H,29H,2DH
- db 3CH,3EH,7BH,7DH,5FH,5CH,5EH,7EH,7CH,60H
- eschlp db cr,lf,'Enter literal value (ex: Cntrl ]) $'
- tophlp db cr,lf,'BYE to host (LOGOUT) and exit to DOS'
- db cr,lf,'CONNECT to host on selected port'
- db cr,lf,'EXIT to DOS'
- db cr,lf,'FINISH running Kermit on the host'
- db cr,lf,'HELP by giving this message'
- db cr,lf,'LOGOUT the host'
- db cr,lf,'RECEIVE file from host'
- db cr,lf,'SEND file to host'
- db cr,lf,'SET a parameter'
- ; db cr,lf,'SHOW the parameters'
- db cr,lf,'STATUS of Kermit$'
- sethlp db cr,lf,'BACKARROW to' ; [19c]
- db cr,lf,'BAUD rate'
- db cr,lf,'BELL' ; [17a]
- db cr,lf,'DEBUG'
- db cr,lf,'END-OF-LINE character'
- db cr,lf,'ESCAPE character change'
- db cr,lf,'FILE-WARNING'
- IF ibmpc
- db cr,lf,'HEATH-19' ; [19e]
- ENDIF
- db cr,lf,'IBM'
- db cr,lf,'INCOMPLETE file' ; [20d]
- db cr,lf,'LOCAL-ECHO echoing (half-duplex)'
- db cr,lf,'PARITY type' ; [10]
- IF ibmpc
- db cr,lf,'PORT for communication$' ; [19b]
- ; db cr,lf,'VT52-EMULATION$' ; [19e]
- ENDIF
- IF Z100
- db '$'
- ENDIF
- stshlp db cr,lf,'PAD-CHAR'
- db cr,lf,'PADDING$'
- onhlp db cr,lf,'OFF ON$'
- yeshlp db cr,lf,'NO YES$'
- abfhlp db cr,lf,'DISCARD KEEP$' ; [20d]
- comphlp db cr,lf,'1 (COM1) 2 (COM2)$' ; [19b]
- parhlp db cr,lf,'None Mark Odd Even Space$' ; [10]
- IF ibmpc
- bdhlp db cr,lf,'300 1200 1800 2400 4800 9600$'
- ENDIF
- IF Z100
- bdhlp db cr,lf,'45.5 50 75 110 134.5 150 300'
- db ' 600 1200 1800'
- db cr,lf,' 2000 2400 4800 9600 19200 38400'
- ENDIF
- BShlp db cr,lf,'BACKSPACE DELETE$' ; [19c]
- eolhlp db cr,lf,'Decimal digit between 0 and 31$' ; [5]
- eolerr db cr,lf,'Illegal end-of-line character$' ; [5]
- inthlp db cr,lf,'? This message'
- db cr,lf,'C Close the connection'
- db cr,lf,'S Status of the connection'
- db cr,lf,'B Send a break' ; [20g]
- db cr,lf,'Typing the escape character will send it to the host'
- db cr,lf,cr,lf,'Command>$'
- locst db cr,lf,'Local echo on$'
- remst db cr,lf,'Local echo off$'
- belon db cr,lf,'Ring bell at end of transfer$' ; [17a - DT]
- beloff db cr,lf,'No bell at end of transfer$' ; [17a - DT]
- IF ibmpc
- vtemst db cr,lf,'HEATH-19 emulation on$' ; [19e]
- novtst db cr,lf,'HEATH-19 emulation off$' ; [19e]
- cm1st db cr,lf,'Using communications port 1$' ; [19b]
- cm2st db cr,lf,'Using communications port 2$' ; [19b]
- ENDIF
- ibmst db cr,lf,'IBM on$'
- noibm db cr,lf,'IBM off$'
- pnonst db cr,lf,'No parity$' ; [10]
- poddst db cr,lf,'Odd parity$' ; [10]
- pevnst db cr,lf,'Even parity$' ; [10]
- pmrkst db cr,lf,'Mark parity$' ; [10]
- pspcst db cr,lf,'Space parity$' ; [10]
- IF Z100
- b04st db cr,lf,'Baud rate is 45.5$'
- b05st db cr,lf,'Baud rate is 50$'
- b07st db cr,lf,'Baud rate is 75$'
- b11st db cr,lf,'Baud rate is 110$'
- b13st db cr,lf,'Baud rate is 134.5$'
- b15st db cr,lf,'Baud rate is 150$'
- b06st db cr,lf,'Baud rate is 600$'
- b20st db cr,lf,'Baud rate is 2000$'
- b19st db cr,lf,'Baud rate is 19200$'
- b38st db cr,lf,'Baud rate is 38400$'
- ENDIF
- b03st db cr,lf,'Baud rate is 300$'
- b12st db cr,lf,'Baud rate is 1200$'
- b18st db cr,lf,'Baud rate is 1800$'
- b24st db cr,lf,'Baud rate is 2400$'
- b48st db cr,lf,'Baud rate is 4800$'
- b96st db cr,lf,'Baud rate is 9600$'
- debon db cr,lf,'Debug mode on$'
- deboff db cr,lf,'Debug mode off$'
- flwon db cr,lf,'File Warning on$'
- flwoff db cr,lf,'File Warning off$'
- bkbs db cr,lf,'Backarrow sends a backspace $' ; [19c]
- bkdel db cr,lf,'Backarrow sends a delete $' ; [19c]
- abfdst db cr,lf,'Discard incoming file if incomplete $' ;[20d]
- abfkst db cr,lf,'Keep incoming file if incomplete $' ;[20d]
- eolst db cr,lf,'End-of-line character is ^$' ; [5]
- escmes db cr,lf,'Escape character is $' ; [6]
-
-
- outlin db cr,lf,' CUCCA'
- IF ibmpc
- db ' IBM-PC'
- ENDIF
- IF Z100
- db '/Stevens Heath/Zenith Z-100'
- ENDIF
- db ' Kermit-86 V1.20',cr,lf
- db cr,lf,'Number of packets: ' ; [19a]
- db cr,lf,'Number of retries: ' ; [19a]
- db cr,lf,'File name $'
- delstr db 10O,' ',10O,10O,'$' ; Delete string.
- clrspc db ' ',10O,'$' ; Clear space.
- escspc db 10O,' ',10O,'$' ; Clear escape.
- IF ibmpc
- clrlin db cr,'$' ; Clear line (just the cr part).
- ENDIF
- IF Z100
- clrlin db cr,esc,'K$' ; Clear line on Z-100
- clreol db esc,'K$' ; Clear to end of line
- clrscr db esc,'H',esc,'J$' ; Home and clear screen
- homcur db esc,'H$' ; Home cursor
- ENDIF
- prsp db ' $' ; Print a space.
-
- ; Cursor addressing items.
-
- IF ibmpc
- scrhi dw 0434H ; Err when 8th bit is on.
- scrrpr dw 0700H ; Prompt when Kermit ends.
- screrr dw 0600H ; Place for error msgs.
- scrfln dw 050CH ; Place for file name.
- scrnrt dw 0415H ; Place for number of retries.
- scrnp dw 0315H ; Place for number of packets.
- scrfr dw 0600H ; Rename file.
- scrst dw 0334H ; Place for status.
- scrint dw 0434H ; Acknowledge interrupt. [20b]
- scrsp dw 0800H ; Place for send packet.
- scrrp dw 0A00H ; Place for receive packet.
-
- ttab label word ; Table for cursor movement.
- ta dw curup ; Cursor up.
- tb dw curdwn ; Cursor down.
- tc dw currt ; Cursor right.
- td dw curlft ; Cursor left.
- te dw curclr ; Clear display. [15]
- tf dw curskp ; Enter graphics mode.
- tg dw curskp ; Exit graphics mode.
- th dw curhm ; Cursor home.
- ti dw curup ; Reverse line feed.
- tj dw curscr ; Clear to end of screen.
- tk dw curln ; Clear to end of line.
- tl dw inslin ; Insert line.
- tm dw dellin ; Delete line.
- tn dw delchr ; Delete character. [17b]
- to dw insmox ; Cancel Insert Character. [17b]
- ENDIF
-
- IF Z100
- scrhi db esc,'Y',23H,54H,lf,'$' ; 8th bit on in character
- scrrpr db esc,'Y',27H,20H,'$' ; Prompt when Kermit ends
- screrr db esc,'Y',26H,20H,'$' ; Error messages
- scrfln db esc,'Y',25H,2CH,'$' ; File name
- scrnrt db esc,'Y',23H,35H,lf,'$' ; Number of retries
- scrnp db esc,'Y',23H,35H,'$' ; Number of packets
- scrfr db esc,'Y',26H,20H,'$' ; Rename file
- scrst db esc,'Y',23H,54H,'$' ; Status
- scrint db esc,'Y',24H,54H,'$' ; Acknowledge interrupt. [20b]
- scrsp db esc,'Y',28H,20H,'$' ; send packet
- scrrp db esc,'Y',2AH,20H,'$' ; Receive packet
- ENDIF
-
- ; COMND tables
-
- comtab db 0AH ; Ten entries.
- db 03H,'BYE$'
- dw bye
- db 07H,'CONNECT$'
- dw telnet
- db 04H,'EXIT$'
- dw exit
- db 06H,'FINISH$'
- dw finish
- db 04H,'HELP$'
- dw help
- db 06H,'LOGOUT$'
- dw logout
- db 07H,'RECEIVE$'
- dw read
- db 04H,'SEND$'
- dw send
- db 03H,'SET$'
- dw setcom
- db 06H,'STATUS$'
- dw status
-
- IF ibmpc
- settab db 0DH ; Thirteen entries. [17a][19b][19c][20d]
- ENDIF
- IF Z100
- settab db 0BH ; Eleven entries. [10][17a][19c][20d]
- ENDIF
- db 09H,'BACKARROW$' ; [19c]
- dw BSset ; [19c]
- db 04H,'BAUD$'
- dw baudst
- db 04H,'BELL$' ; [17a]
- dw bellst ; [17a]
- db 05H,'DEBUG$'
- dw debst
- db 0BH,'END-OF-LINE$' ; [5]
- dw eolset ; [5]
- db 06H,'ESCAPE$'
- dw escape
- db 0CH,'FILE-WARNING$'
- dw filwar
- IF ibmpc
- db 0DH,'H19-EMULATION$' ; [19e]
- dw vt52em ; [19e]
- ENDIF
- db 03H,'IBM$'
- dw ibmset
- db 0AH,'INCOMPLETE$' ; [20d]
- dw abfset ; [20d]
- db 0AH,'LOCAL-ECHO$'
- dw lcal
- db 06H,'PARITY$' ; [10]
- dw setpar ; [10]
- IF ibmpc
- db 04H,'PORT$' ; [19b]
- dw comset ; [19b]
- ; db 0EH,'VT52-EMULATION$' ; [19e]
- ; dw vt52em ; [19e]
- ENDIF
-
- ontab db 02H ; Two entries.
- db 03H,'OFF$' ; Should be alphabetized. [19a]
- dw 00H
- db 02H,'ON$'
- dw 01H
-
- ; If abort when receiving files, can keep what we have or discard. [20d]
-
- abftab db 02H ; Only two options.
- db 07H,'DISCARD$'
- dw 01H
- db 04H,'KEEP$'
- dw 00H
-
- ; Entries for choosing communications port. [19b]
-
- comptab db 04H
- db 01H,'1$'
- dw 01H
- db 01H,'2$'
- dw 00H
- db 04H,'COM1$'
- dw 01H
- db 04H,'COM2$'
- dw 00H
-
- yestab db 02H ; Two entries.
- db 02H,'NO$'
- dw 00H
- db 03H,'YES$'
- dw 01H
-
- partab db 05H ; Five entries. [10 start]
- db 04H,'EVEN$'
- dw PAREVN
- db 04H,'MARK$'
- dw PARMRK
- db 04H,'NONE$'
- dw PARNON
- db 03H,'ODD$'
- dw PARODD
- db 05H,'SPACE$'
- dw PARSPC ;[10 end]
-
- BStab db 02H ;Two entries [19c start]
- db 09H,'BACKSPACE$'
- dw 00H
- db 06H,'DELETE$'
- dw 01H ;[19c]
-
- IF ibmpc
- bdtab db 06H ; Six entries.
- db 04H,'1200$'
- dw B1200
- db 04H,'1800$'
- dw B1800
- db 04H,'2400$'
- dw B2400
- db 03H,'300$'
- dw B0300
- db 04H,'4800$'
- dw B4800
- db 04H,'9600$'
- dw B9600
- ENDIF
- IF Z100
- bdtab db 010H ; 16 entries
- db 03H,'110$'
- dw b0110
- db 04H,'1200$'
- dw b1200
- db 03H,'134$'
- dw b01345
- db 03H,'150$'
- dw b0150
- db 04H,'1800$'
- dw b1800
- db 05H,'19200$'
- dw b19200
- db 04H,'2000$'
- dw b2000
- db 04H,'2400$'
- dw b2400
- db 03H,'300$'
- dw b0300
- db 05H,'38400$'
- dw b38400
- db 02H,'45$'
- dw b00455
- db 04H,'4800$'
- dw b4800
- db 02H,'50$'
- dw b0050
- db 03H,'600$'
- dw b0600
- db 02H,'75$'
- dw b0075
- db 04H,'9600$'
- dw b9600
- ENDIF
-
- ; COMND storage
-
- cmer00 db cr,lf,'?Program error Invalid COMND call$'
- cmer01 db cr,lf,'?Ambiguous$'
- cmer02 db cr,lf,'?Illegal input file spec$'
- ;cmer03 db cr,lf,'?Unrecognized instruction$'
- cmer03 db cr,lf,'?Invalid command$' ; [19e]
- cmer04 db cr,lf,'?Invalid command or operand$' ; [1]
- cmin00 db ' Confirm with carriage return$'
- cmcrlf db cr,lf,'$'
-
- cmstat db ? ; What is presently being parsed.
- cmaflg db ? ; Non-zero when an action char has been found.
- cmccnt db ? ; Non-zero if a significant char is found.
- cmsflg db ? ; Non-zero when the last char was a space.
- cmostp dw ? ; Old stack pointer for reparse.
- cmrprs dw ? ; Address to go to on reparse.
- cmprmp dw ? ; Address of prompt.
- cmptab dw ? ; Address of present keyword table.
- cmhlp dw ? ; Address of present help.
- cmdbuf db 80H DUP(?) ; Buffer for command parsing.
- cmfcb dw ? ; Pointer to FCB.
- cmfcb2 dw ? ; Pointer to position in FCB.
- cmcptr dw ? ; Pointer for next char input.
- cmdptr dw ? ; Pointer into the command buffer.
- cmsiz dw ? ; Size info of user input.
- cmkptr dw ? ; Pointer to keyword.
- cmsptr dw ? ; Place to save a pointer.
- cmchr db ? ; Save char when checking ambiguity.
-
- ; Program storage.
-
- oldstk dw ? ; Storage for system stack.
- oldsts dw ? ; System stack segment.
- ssp dw 0 ; Save SP in Telnet.
- bufhex dw 80H
- filsiz dd 0 ; Double word for filesize (in bytes.)
- eoflag db ? ; EOF flag; non-zero on EOF.
- wldflg db 0 ; Assume no "*" in fn. [7]
- ;telflg db 0 ; Are we acting as a terminal. [16] [17c]
- belflg db 1 ; Use bell [17a -- DT]
- comflg db 1 ; Use COM1 by default. [19b]
- cxzflg db 0 ; ^X/^Z to interrupt file x-fer. [20b]
- abfflg db 1 ; Discard incoming file if abort. [20d]
- debug db 0 ; Debugging mode (default off).
- hierr db 0 ; Non-ascii char (non-zero if yes).
- filflg db ? ; Non-zero when nothing in DMA buffer.
- ecoflg db 0 ; Local echo flag (default off).
- parflg db defpar ; Parity flag (default none.) [10]
- escflg db 0 ; Escape flag (start off).
-
- IF ibmpc
- vtflg db 1 ; VT52 emulation flag (default on).
- incmod db 0 ; Insert Character mode. [17b] [20g]
- curatt dw 0007H ; Video attributes. [17b]
- baud dw B4800 ; Use default of 4800.
- mddat dw MDMDAT1 ; Default to port 1. [19b start]
- mdstat dw MDMSTS1 ; Ditto.
- mdcom dw MDMCOM1 ; Here too.
- mden db MDMINTO
- mddis db MDMINTC
- mdmeoi db EOICOM
- mdintv dw MDMINTV ; [19b end]
- ENDIF
- IF Z100
- auxcnf db 4 dup(?) ; AUX port configuration info
- baud db ? ; Baud rate
- auxcnf1 db 12 dup(?) ; Rest of configuration info
- mdcom dw MDMCOM ; Use to send a break. [20g]
- ENDIF
-
- flwflg db 1 ; File warning flag (default on). [19c]
- ibmflg db 0 ; IBM flag (default off).
- delflg db 1 ; Do BS to DEL translation. [19c]
- extflg db 0 ; Exit flag (default off).
- escchr db defesc ; Storage for the escape character.
- incnt dw ? ; Number of chars read in from port.
- chrcnt dw ? ; Number of chars in the file buffer.
- filcnt dw ? ; Number of chars left to fill.
- outpnt dw ? ; Position in packet.
- bufpnt dw ? ; Position in file buffer.
- fcbptr dw ? ; Position in FCB.
- datptr dw ? ; Position in packet data buffer.
- cbfptr dw ? ; Position in character buffer.
- pktptr dw ? ; Poistion in receive packet.
- siz dw ? ; Size of data from gtchr.
- spsiz db dspsiz ; Send packet size.
- rpsiz db drpsiz ; Receive packet size.
- stime db dstime ; Send time out.
- rtime db drtime ; Receive time out.
- spad db dspad ; Send padding.
- rpad db drpad ; Receive padding.
- spadch db dspadc ; Send padding char.
- rpadch db drpadc ; Receive padding char.
- seol db dseol ; Send EOL char.
- reol db dreol ; Receive EOL char.
- squote db dsquot ; Send quote char.
- rquote db drquot ; Receive quote char.
- pktnum dw ? ; Packet number.
- numpkt dw ? ; Total number of packets sent.
- numrtr dw ? ; Total number of retries.
- numtry db ? ; Number of tries on this packet.
- oldtry db ? ; Number of tries on previous packet.
- state db ? ; Present state of the automaton.
- savsci dw ? ; Save for serial port interrupt vector. [14]
- savscs dw ? ; Ditto. [14]
- packet db ?,?,?,? ; Packet (data is part of it).
- data db 5AH DUP(?) ; Data and checksum field of packet.
- recpkt db 60H DUP(?) ; Receive packet storage (use the following).
- filbuf db 60H DUP(?) ; Character buffer.
- fcb db 25H DUP(?) ; Use as our FCB.
- cpfcb db 25H DUP(?) ; Save FCB in case of "*". [7]
- buff db 80H DUP(?) ; Use as our DAT.
- rdbuf db 80H DUP(?)
- cnt dw 0
- temp dw 0
- temp1 dw ? ; Temporary storage.
- temp2 dw ?
- temp3 dw ?
- temp4 dw ?
- argblk dw ? ; For subroutine arguments.
- argbk1 dw ?
- argbk2 dw ?
- argbk3 dw ?
-
- DATAS ENDS ; End data segment
-
-
- MAIN SEGMENT PARA PUBLIC 'MAIN'
- START PROC FAR
- ASSUME CS:MAIN,DS:DATAS,SS:STACK,ES:NOTHING
-
- push ds ; Save system data area.
- sub ax,ax ; Get a zero.
- push ax ; Put zero return addr on stack.
-
- mov ax,datas ; Initialize DS.
- mov ds,ax
- sub ax,ax
-
- mov oldstk,sp ; Save old stack pointer.
-
- call cmblnk ; Clear the screen.
- call locate
-
- mov ah,prstr ; Print the version header.
- mov dx,offset versio
- int dos
-
- mov ah,setdma ; Set disk transfer address.
- mov dx,offset buff
- int dos
-
- call dobaud ; Set the baud rate. [19a, 20g]
-
- ; This is the main KERMIT loop. It prompts for and gets the users commands.
-
- kermit: mov dx,offset kerm
- call prompt ; Prompt the user.
- mov dx,offset comtab
- mov bx,offset tophlp
- mov ah,cmkey
- call comnd
- jmp kermt2
- call bx ; Call the routine returned.
- jmp kermt3
- cmp extflg,0 ; Check if the exit flag is set.
- jne krmend ; If so jump to KRMEND.
- jmp kermit ; Do it again.
-
- kermt2: mov ah,prstr
- mov dx,offset ermes1 ; Give an error.
- int dos
- jmp kermit
-
- kermt3: mov ah,prstr
- mov dx,offset ermes3 ; Give an error.
- int dos
- jmp kermit
-
- krmend:
- mov sp,oldstk
- ret
-
- START ENDP
-
-
- ; These are some utility routines.
-
- ; Abort
-
- ABORT PROC NEAR
- mov state,'A' ; Otherwise abort.
- ret
- ABORT ENDP
-
- ; NAK
-
- NAK PROC NEAR
- mov ax,pktnum ; Get the packet number we're waiting for.
- mov argblk,ax
- mov argbk1,0
- mov ah,'N' ; NAK that packet.
- call spack
- jmp abort
- nop ; So 'jmp rskp' in SPACK comes here. [19a]
- ret ; Go around again.
- NAK ENDP
-
- ; Position cursor for an error message.
-
- ERPOS PROC NEAR
- IF ibmpc
- mov ah,2
- mov bh,0
- mov dx,screrr
- int bios
- ret
- ENDIF
- IF Z100
- mov dx,offset screrr ; Get address of string to position cursor
- mov ah,prstr ; Get the function code
- int dos ; Print the addressing string
- ret ; And return
- ENDIF
- ERPOS ENDP
-
- ; Position cursor for number of retries message.
-
- RTPOS PROC NEAR
- IF ibmpc
- mov ah,2
- mov bh,0
- mov dx,scrnrt
- int bios
- ret
- ENDIF
- IF Z100
- mov ah,prstr ; Get the function to print string
- mov dx,offset scrnrt ; Get the address of the string
- int dos ; Print the string
- ret ; And return
- ENDIF
- RTPOS ENDP
-
- ; Reassure user that we acknowledge his ^X/^Z. [20b]
- INTMSG PROC NEAR
- IF ibmpc ; Tell user we acknowledge it.
- mov ah,2
- mov dx,scrint
- mov bh,0
- int bios
- ENDIF
- IF Z100
- mov ah,prstr ; Get print string function
- mov dx,offset scrint ; and string to move cursor
- int dos ; Print the string
- ENDIF
- mov dx,offset infms7 ; File interrupted?
- cmp cxzflg,'X' ; Yes.
- je int0
- mov dx,offset infms8 ; File group interrupted.
- int0: mov ah,prstr
- int dos
- ret
- INTMSG ENDP
-
- ; Print err message that found a non-standard-Ascii char in the file.
-
- BITERR PROC NEAR
- push bx
- IF ibmpc
- mov ah,2
- mov bh,0
- mov dx,scrhi
- int bios
- ENDIF
- IF Z100
- mov ah,prstr ; Get the function to print string
- mov dx,offset scrhi ; Get the address of the string
- int dos ; Print the string
- ENDIF
- mov ah,prstr
- mov dx,offset hibit
- int dos
- pop bx
- ret
- BITERR ENDP
-
- ; This routine prints out the escape character in readable format.
-
- ESCPRT PROC NEAR ; [6 start]
- mov dl,escchr
- cmp dl,' '
- jge escpr2
- push dx
- mov ah,prstr
- mov dx,offset esctl
- int dos
- pop dx
- add dl,040H ; Make it printable.
- escpr2: mov ah,conout
- int dos
- ret
- ESCPRT ENDP ; [6 end]
-
- ; FCB must be remembered if found "*" in filename. [7 start]
- ; Copy from place addressed by BX to place addressed by DI.
- ; Also use to get the filename to the FCB from the DTA.
-
- FCBCPY PROC NEAR
- fcbcp1: cmp cl,0
- je fcbcp2
- mov ah,[bx]
- mov [di],ah
- dec cl
- inc bx
- inc di
- jmp fcbcp1
- fcbcp2: ret
- FCBCPY ENDP
-
- ; This routine sets up the data for init packet (either the
- ; Send_init or ACK packet).
-
- RPAR PROC NEAR
- mov ah,rpsiz ; Get the receive packet size.
- add ah,' ' ; Add a space to make it printable.
- mov [bx],ah ; Put it in the packet.
- mov ah,rtime ; Get the receive packet time out.
- add ah,' ' ; Add a space.
- mov 1[bx],ah ; Put it in the packet.
- mov ah,rpad ; Get the number of padding chars.
- add ah,' '
- mov 2[bx],ah ; Put it in the packet.
- mov ah,rpadch ; Get the padding char.
- add ah,100O ; Uncontrol it.
- and ah,7FH
- mov 3[bx],ah ; Put it in the packet.
- mov ah,reol ; Get the EOL char.
- add ah,' '
- mov 4[bx],ah ; Put it in the packet.
- mov ah,rquote ; Get the quote char.
- mov 5[bx],ah ; Put it in the packet.
- mov ah,06H ; Six pieces of data.
- ret
- RPAR ENDP
-
- ; This routine reads in all the send_init packet information.
-
- SPAR PROC NEAR
- mov temp4,ax ; Save the number of arguments.
- mov ah,[bx] ; Get the max packet size.
- sub ah,' ' ; Subtract a space.
- mov spsiz,ah ; Save it.
- mov ax,temp4
- cmp al,3 ; Fewer than three pieces?
- jge spar1
- ret ; If so we are done.
- spar1: mov ah,2[bx] ; Get the number of padding chars.
- sub ah,' '
- mov spad,ah
- mov ax,temp4
- cmp al,4 ; Fewer than four pieces?
- jge spar2
- ret ; If so we are done.
- spar2: mov ah,3[bx] ; Get the padding char.
- add ah,100O ; Re-controlify it.
- and ah,7FH
- mov spadch,ah
- mov ax,temp4
- cmp al,5 ; Fewer than five pieces?
- jge spar3
- ret ; If so we are done.
- spar3: mov ah,4[bx] ; Get the EOL char.
- sub ah,' '
- mov seol,ah
- mov ax,temp4
- cmp al,6 ; Fewer than six pieces?
- jge spar4
- ret ; If so we are done.
- spar4: mov ah,5[bx] ; Get the quote char.
- mov squote,ah
- ret
- SPAR ENDP
-
-
- ; Initialize buffers and clear line.
-
- INIT PROC NEAR
- call cmblnk
- call locate
- mov ah,prstr ; Put statistics headers on the screen.
- mov dx,offset outlin
- int dos
- call init1
- ret
- INIT ENDP
-
- INIT1 PROC NEAR
- mov chrcnt,bufsiz ; Number of chars left.
- mov bufpnt,offset buff ; Addr for beginning.
- ret
- INIT1 ENDP
-
- ; Clear out message about interrupted file. [20b]
- CXMSG PROC NEAR
- IF ibmpc
- mov ah,2
- mov bh,0
- mov dx,scrint
- int bios
- mov ax,0920H
- mov bx,7
- mov cx,26
- int bios
- ret
- ENDIF
- IF Z100
- mov ah,prstr
- mov dx,offset scrint ; Move the cursor.
- int dos
- mov ah,prstr ; Get the function again
- mov dx,offset clreol ; And the sequence to clear to EOL
- int dos ; Do it
- ret
- ENDIF
- CXMSG ENDP
-
- ; Clear out the old filename on the screen.
-
- CLRFLN PROC NEAR
- IF ibmpc
- mov ah,2
- mov bh,0
- mov dx,scrfln
- int bios
- call clreol ; Clear to end of line. [19a]
- ret
- ENDIF
- IF Z100
- mov ah,prstr ; Get print string function
- mov dx,offset scrfln ; and string to move cursor
- int dos ; Print the string
- mov ah,prstr ; Get the function again
- mov dx,offset clreol ; And the sequence to clear to EOL
- int dos ; Do it
- ret ; And return
- ENDIF
- CLRFLN ENDP
-
- ; RECEIVE command
-
- READ PROC NEAR
- mov bx,offset data ; Where to put text (if any). [8 start]
- mov ah,cmtxt
- call comnd ; Get text or confirm.
- jmp kermt3
- cmp ah,0 ; Read in any chars?
- je read1 ; A regular receive.
- mov al,ah
- mov ah,0
- mov argbk1,ax ; Remember number of chars we read.
- mov ah,'$' ; Use for printing.
- mov [bx],ah
- call init ; Clear line and initialize buffers.
- call clrfln ; Prepare to print filename.
- mov ah,prstr
- mov dx,offset data ; Print file name.
- int dos
- mov argblk,0 ; Start at packet zero.
- mov ah,'R' ; Receive init packet.
- call spack ; Send the packet.
- jmp kermt3
- jmp read12 ; [8 end]
- read1: call init ; Clear the line and initialize the buffers.
- read12: mov numpkt,0 ; Set the number of packets to zero.
- mov numrtr,0 ; Set the number of retries to zero.
- mov pktnum,0 ; Set the packet number to zero.
- mov numtry,0 ; Set the number of tries to zero.
- mov cxzflg,0 ; Reset ^X/^Z flag. [20c]
- call serini ; Initialize serial port. [14]
- call rtpos ; Position cursor.
- mov ax,numrtr
- call nout ; Write the number of retries.
- mov state,'R' ; Set the state to receive initiate.
- read2:
- IF ibmpc
- mov ah,2 ; Position cursor.
- mov dx,scrst
- mov bh,0
- int bios
- ENDIF
- IF Z100
- mov ah,prstr ; Get print string function
- mov dx,offset scrst ; and string to move cursor
- int dos ; Print the string
- ENDIF
- mov ah,prstr ; Be informative.
- mov dx,offset infms1
- int dos
- IF ibmpc
- mov ah,2
- mov dx,scrnp
- mov bh,0
- int bios
- ENDIF
- IF Z100
- mov ah,prstr ; Get print string function
- mov dx,offset scrnp ; and string to move cursor
- int dos ; Print the string
- ENDIF
- mov ax,numpkt
- call nout ; Write the number of packets.
- mov ah,state ; Get the state.
- cmp ah,'D' ; Are we in the data send state?
- jne read3
- call rdata
- jmp read2
- read3: cmp ah,'F' ; Are we in the file receive state?
- jne read4
- call rfile ; Call receive file.
- jmp read2
- read4: cmp ah,'R' ; Are we in the receive initiate state?
- jne read5
- call rinit
- jmp read2
- read5: cmp ah,'C' ; Are we in the receive complete state?
- jne read6
- call serrst ; Reset serial port. [14]
- IF ibmpc
- mov ah,2 ; Position cursor.
- mov dx,scrst
- mov bh,0
- int bios
- ENDIF
- IF Z100
- mov ah,prstr ; Get print string function
- mov dx,offset scrst ; and string to move cursor
- int dos ; Print the string
- ENDIF
- mov ah,prstr
- mov dx,offset infms3 ; Plus a little cuteness.
- cmp cxzflg,0 ; Completed or interrupted? [20c]
- je read13 ; Ended normally. [20c]
- mov dx,offset infms6 ; Say was interrupted. [20c]
- read13: int dos
- cmp belflg,0 ; Bell desired? [17a]
- je readnb ; No. [17a]
- mov dx,offset ender ; Ring them bells. [4]
- int dos ; [4]
- readnb: ; [17a -- new label]
- IF ibmpc
- mov ah,2
- mov dx,scrrpr ; Put prompt here.
- mov bh,0
- int bios
- ENDIF
- IF Z100
- mov ah,prstr ; Get print string function
- mov dx,offset scrrpr ; and string to move cursor
- int dos ; Print the string
- ENDIF
- jmp rskp
- read6: call serrst ; Reset serial port. [14]
- IF ibmpc
- mov ah,2 ; Position cursor.
- mov dx,scrst
- mov bh,0
- int bios
- ENDIF
- IF Z100
- mov ah,prstr ; Get print string function
- mov dx,offset scrst ; and string to move cursor
- int dos ; Print the string
- ENDIF
- mov ah,prstr
- mov dx,offset infms4 ; Plus a little cuteness.
- int dos
- cmp belflg,0 ; Bell desired? [17a]
- je read7 ; No. [17a]
- mov dx,offset ender ; Ring them bells. [4]
- int dos ; [4]
- read7:
- IF ibmpc
- mov ah,2
- mov dx,scrrpr
- mov bh,0
- int bios
- ENDIF
- IF Z100
- mov ah,prstr ; Get print string function
- mov dx,offset scrrpr ; and string to move cursor
- int dos ; Print the string
- ENDIF
- jmp rskp
- READ ENDP
-
-
- ; Receive routines
-
- ; Receive init
-
- RINIT PROC NEAR
- mov ah,numtry ; Get the number of tries.
- cmp ah,imxtry ; Have we reached the maximum number of tries?
- jl rinit2
- call erpos ; Position cursor.
- mov dx,offset ermes7
- mov ah,prstr
- int dos ; Print an error message.
- jmp abort ; Change the state to abort.
- rinit2: inc ah ; Increment it.
- mov numtry,ah ; Save the updated number of tries.
- call rpack ; Get a packet.
- jmp nak ; Trashed packet: nak, retry.
- cmp ah,'S' ; Is it a send initiate packet?
- jne rinit3 ; If not see if its an error.
- mov ah,numtry ; Get the number of tries.
- mov oldtry,ah ; Save it.
- mov numtry,0 ; Reset the number of tries.
- mov ax,argblk ; Returned packet number. (Synchronize them.)
- inc ax ; Increment it.
- and ax,3FH ; Turn off the two high order bits.
- mov pktnum,ax ; Save modulo 64 of the number.
- mov bx,numpkt
- inc bx ; Increment the number of packets.
- mov numpkt,bx
- mov ax,argbk1 ; Get the number of arguments received.
- mov bx,offset data ; Get a pointer to the data.
- call spar ; Get the data into the proper variables.
- mov bx,offset data ; Get a pointer to our data block.
- call rpar ; Set up the receive parameters.
- xchg ah,al
- mov ah,0
- mov argbk1,ax ; Store the returned number of arguments.
- mov ah,'Y' ; Acknowledge packet.
- call spack ; Send the packet.
- jmp abort
- mov ah,'F' ; Set the state to file send.
- mov state,ah
- ret
- rinit3: cmp ah,'E' ; Is it an error packet?
- jne rinit4
- call error
- rinit4: jmp abort
- RINIT ENDP
-
-
- ; Receive file
-
- RFILE PROC NEAR
- cmp numtry,maxtry ; Have we reached the maximum number of tries?
- jl rfile1
- call erpos ; Position cursor.
- mov dx,offset ermes8
- mov ah,prstr
- int dos ; Print an error message.
- jmp abort ; Change the state to abort.
- rfile1: inc numtry ; Save the updated number of tries.
- call rpack ; Get a packet.
- jmp nak ; Trashed packet: nak, retry.
- cmp ah,'S' ; Is it a send initiate packet?
- jne rfile2 ; No, try next type.
- cmp oldtry,imxtry ; Have we reached the maximum number of tries?
- jl rfil12 ; If not proceed.
- call erpos ; Position cursor.
- mov dx,offset ermes7
- mov ah,prstr
- int dos ; Print an error message.
- jmp abort ; Change the state to abort.
- rfil12: inc oldtry ; Save the updated number of tries.
- mov ax,pktnum ; Get the present packet number.
- cmp ax,0 ; Had we wrapped around? [18 start]
- jne rfilx
- mov ax,64
- rfilx: dec ax ; Decrement. [18 end -- new label]
- cmp ax,argblk ; Is the packet's number one less than now?
- je rfil13
- jmp nak ; No, NAK and try again.
- rfil13: call rtpos ; Position cursor.
- inc numrtr ; Increment the number of retries.
- mov ax,numrtr
- call nout ; Write the number of retries.
- mov numtry,0 ; Reset the number of tries.
- mov bx,offset data ; Get a pointer to our data block.
- call rpar ; Set up the parameter information.
- xchg ah,al
- mov ah,0
- mov argbk1,ax ; Save the number of arguments.
- mov ah,'Y' ; Acknowledge packet.
- call spack ; Send the packet.
- jmp abort
- ret
- rfile2: cmp ah,'Z' ; Is it an EOF packet?
- jne rfile3 ; No, try next type.
- cmp oldtry,maxtry ; Have we reached the maximum number of tries?
- jl rfil21 ; If not proceed.
- call erpos ; Position cursor.
- mov dx,offset ermes9
- mov ah,prstr
- int dos ; Print an error message.
- jmp abort ; Change the state to abort.
- rfil21: inc oldtry ; Increment it.
- mov ax,pktnum ; Get the present packet number.
- cmp ax,0 ; Had we wrapped around? [18 start]
- jne rfily
- mov ax,64
- rfily: dec ax ; Decrement. [18 end -- new label]
- cmp ax,argblk ; Is the packet's number one less than now?
- je rfil24
- jmp nak ; No, NAK and try again.
- rfil24: call rtpos ; Position cursor.
- inc numrtr ; Increment the number of retries
- mov ax,numrtr
- call nout ; Write the number of retries.
- mov numtry,0
- mov argbk1,0 ; No data. (The packet number is in argblk.)
- mov ah,'Y' ; Acknowledge packet.
- call spack ; Send the packet.
- jmp abort
- ret
- rfile3: cmp ah,'F' ; Start of file?
- jne rfile4
- mov ax,argblk ; Get the packet number.
- cmp ax,pktnum ; Is it the right packet number?
- je rfil32
- jmp nak ; No, NAK it and try again.
- rfil32: inc ax ; Increment the packet number.
- and ax,3FH ; Turn off the two high order bits.
- mov pktnum,ax ; Save modulo 64 of the number.
- inc numpkt ; Increment the number of packets.
- call gofil ; Get a file to write to.
- jmp abort
- call init1 ; Initialize all the buffers.
- mov ah,numtry ; Get the number of tries.
- mov oldtry,ah ; Save it.
- mov numtry,0 ; Reset the number of tries.
- mov argbk1,0 ; No data. (The packet number is in argblk.)
- mov ah,'Y' ; Acknowledge packet.
- call spack ; Send the packet.
- jmp abort
- mov state,'D' ; Set the state to data receive.
- ret
- rfile4: cmp ah,'B' ; End of transmission.
- jne rfile5
- mov ax,pktnum
- cmp ax,argblk ; Do we match?
- je rfil41
- jmp nak ; No, NAK it and try again.
- rfil41: mov argbk1,0 ; No data. (Packet number already in argblk).
- mov ah,'Y' ; Acknowledge packet.
- call spack ; Send the packet.
- jmp abort
- mov state,'C' ; Set the state to complete.
- ret
- rfile5: cmp ah,'E' ; Is it an error packet.
- jne rfile6
- call error
- rfile6: jmp abort
- RFILE ENDP
-
-
- ; Receive data
-
- RDATA PROC NEAR
- cmp numtry,maxtry ; Get the number of tries.
- jl rdata1
- call erpos ; Position cursor.
- mov dx,offset erms10
- mov ah,prstr
- int dos ; Print an error message.
- jmp abort ; Change the state to abort.
- rdata1: inc numtry ; Save the updated number of tries.
- call rpack ; Get a packet.
- jmp nak ; Trashed packet: nak, retry.
- cmp ah,'D' ; Is it a data packet?
- je rdat11
- jmp rdata2 ; No, try next type.
- rdat11: mov ax,pktnum ; Get the present packet number.
- cmp ax,argblk ; Is the packet's number correct?
- jz rdat14
- cmp oldtry,maxtry ; Have we reached the maximum number of tries?
- jl rdat12 ; If not proceed.
- call erpos ; Position cursor.
- mov dx,offset erms10
- mov ah,prstr
- int dos ; Print an error message.
- jmp abort ; Change the state to abort.
- rdat12: inc oldtry ; Save the updated number of tries.
- ; dec pktnum ; Decrement present packet number. [14]
- mov ax,pktnum
- cmp ax,0 ; Had we wrapped around? [18 start]
- jne rdatx
- mov ax,64
- rdatx: dec ax ; [14] [18 end -- new label]
- cmp ax,argblk ; Is the packet's number one less than now?
- je rdat13
- jmp nak ; No, NAK it and try again.
- rdat13: call rtpos ; Position cursor.
- inc numrtr ; Increment the number of retries
- mov ax,numrtr
- call nout ; Write the number of retries.
- mov numtry,0 ; Reset number of tries.
- mov argbk1,0 ; No data. (The packet number is in argblk.)
- mov ah,'Y' ; Acknowledge packet.
- call spack ; Send the packet.
- jmp abort
- ret
- rdat14: inc ax ; Increment the packet number.
- and ax,3FH ; Turn off the two high order bits.
- mov pktnum,ax ; Save modulo 64 of the number.
- inc numpkt ; Increment the number of packets.
- mov ah,numtry ; Get the number of tries.
- mov oldtry,ah ; Save it.
- mov ax,argbk1 ; Get the length of the data.
- cmp cxzflg,0 ; Has the user typed a ^X or ^Z? [20c]
- jne rdat15 ; If yes don't write data out to file. [20c]
- call ptchr
- jmp abort ; Unable to write out chars; abort.
- rdat15: mov numtry,0 ; Reset the number of tries.
- mov argbk1,0 ; No data. (Packet number still in argblk.)
- cmp cxzflg,0 ; Interrupt file transfer? [20c]
- je rdat16 ; Nope. [20c]
- mov bx,offset data ; Send data in ACK in case remote... [20c]
- mov ah,cxzflg ; ... knows about ^X/^Z. [20c]
- mov [bx],ah ; Put data into the packet. [20c]
- mov argbk1,1 ; Set data size to 1. [20c]
- rdat16: mov ah,'Y' ; Acknowledge packet.
- call spack ; Send the packet.
- jmp abort
- ret
- rdata2: cmp ah,'F' ; Start of file?
- jne rdata3 ; No, try next type.
- cmp oldtry,maxtry ; Have we reached the maximum number of tries?
- jl rdat21 ; If not proceed.
- call erpos ; Position cursor.
- mov dx,offset ermes8
- mov ah,prstr
- int dos ; Print an error message.
- jmp abort ; Change the state to abort.
- rdat21: inc oldtry ; Save the updated number of tries.
- mov ax,pktnum
- cmp ax,0 ; Had we wrapped around? [18 start]
- jne rdaty
- mov ax,64
- rdaty: dec ax ; [14 Omitted accidentally - D.T.] [18 end]
- cmp ax,argblk ; Is the packet's number one less than now?
- je rdat22
- jmp nak ; No, NAK it and try again.
- rdat22: call rtpos ; Position cursor.
- inc numrtr ; Increment the number of retries
- mov ax,numrtr
- call nout ; Write the number of retries.
- mov numtry,0 ; Reset number of tries.
- mov argbk1,0 ; No data. (The packet number is in argblk.)
- mov ah,'Y' ; Acknowledge packet.
- call spack ; Send the packet.
- jmp abort
- ret
- rdata3: cmp ah,'Z' ; Is it a EOF packet?
- je rdat3x ; [13]
- jmp rdata4 ; Try and see if its an error. [13]
- rdat3x: mov ax,pktnum ; Get the present packet number. [13]
- cmp ax,argblk ; Is the packet's number correct?
- je rdat32
- jmp nak ; No, NAK it and try again.
- rdat32: inc ax ; Increment the packet number.
- and ax,3FH ; Turn off the two high order bits.
- mov pktnum,ax ; Save modulo 64 of the number.
- inc numpkt
- cmp cxzflg,0 ; Do we want to discard the file? [20c]
- jne rdt32x ; Yes. [20c]
- cmp argbk1,1 ; One piece of data? [20c]
- jne rdat33 ; Nope - finish writing out file? [20c]
- mov bx,offset data ; Get data area. [20c]
- mov ah,[bx] ; Get the data. [20c]
- cmp ah,'D' ; "D" for discard? [20c]
- jne rdat33 ; Nope - write out file. [20c]
- rdt32x: mov ah,delf ; Delete the file if opened. [20c]
- mov dx,offset fcb ; Give the file parameters. [20c]
- int dos ; Kill it, ignore errors. [20c]
- cmp cxzflg,'X' ; Kill one file or all? [20c]
- jne rdat36 ; No so leave flag alone. [20c]
- call cxmsg ; Clear msg about interrupt. [20c]
- mov cxzflg,0 ; Reset - ^X only kills one file. [20c]
- jmp rdat36
- rdat33: mov bx,bufpnt ; Get the dma pointer.
- mov ax,80H
- sub ax,chrcnt ; Get the number of chars left in the DMA.
- cmp ax,80H ; [13 start]
- jne rdat34
- call outbuf ; Write out buffer if no room for ^Z.
- jmp abort
- mov ax,0 ; [13 end]
- rdat34: mov cl,'Z'-100O ; Put in a ^Z for EOF.
- mov [bx],cl
- inc ax
- dec chrcnt
- mov cx,chrcnt
- mov temp,cx
- inc bx
- rdt3: inc ax
- cmp ax,80H
- jg rdat35 ; Pad till full.
- mov cl,0 ; Use nulls.
- mov [bx],cl
- inc bx
- jmp rdt3
- rdat35: call outbuf ; Output the last buffer.
- jmp abort ; Give up if the disk is full.
- call fixfcb
- mov ah,closf ; Close up the file.
- mov dx,offset fcb
- int dos
- rdat36: mov ah,numtry ; Get the number of tries.
- mov oldtry,ah ; Save it.
- mov numtry,0 ; Reset the number of tries.
- mov argbk1,0 ; No data. (The packet number is in argblk.)
- mov ah,'Y' ; Acknowledge packet.
- call spack ; Send the packet.
- jmp abort
- mov state,'F'
- ret
- rdata4: cmp ah,'E' ; Is it an error packet.
- jne rdata5
- call error
- rdata5: jmp abort
- RDATA ENDP
-
- FIXFCB PROC NEAR
- mov bx,offset fcb+18
- mov di,offset filsiz
- mov ax,[bx]
- mov [di],ax
- mov bx,offset fcb+16
- mov ax,[bx]
- mov 2[di],ax
- mov ax,temp ; Get number of chars in last buffer full.
- sub filsiz+2,ax ; Get real file size.
- sbb filsiz,0
- mov bx,offset fcb+18
- mov di,offset filsiz
- mov ax,[di]
- mov [bx],ax
- mov bx,offset fcb+16
- mov ax,2[di]
- mov [bx],ax
- ret
- FIXFCB ENDP
-
-
- ; Send command
-
- SEND PROC NEAR
- mov ah,cmifi ; Parse an input file spec.
- mov dx,offset fcb ; Give the address for the FCB.
- call comnd
- jmp r ; Give up on bad parse.
- send1: mov ah,cmcfm
- call comnd ; Get a confirm.
- jmp r ; Didn't get a confirm.
- send11: mov ah,sfirst ; Get the first file.
- mov dx,offset fcb
- int dos
- cmp al,0FFH ; Any found?
- jne send12
- mov ah,prstr
- mov dx,offset crlf
- int dos
- mov ah,prstr
- mov dx,offset erms15
- int dos
- ret
- send12: cmp wldflg,0 ; Any wildcards. [7 start]
- je send16 ; Nope, so no problem.
- mov bx,offset fcb ; Remember what FCB looked like.
- mov di,offset cpfcb
- mov cl,37 ; Size of FCB.
- call fcbcpy
- mov di,offset fcb+1 ; Copy filename from DTA to FCB.
- mov bx,offset buff+1
- mov cl,11
- call fcbcpy ; [7 end]
- send16: call init ; Clear the line and initialize the buffers.
- call serini ; Initialize serial port. [14]
- mov pktnum,0 ; Set the packet number to zero.
- mov numtry,0 ; Set the number of tries to zero.
- mov numpkt,0 ; Set the number of packets to zero.
- mov numrtr,0 ; Set the number of retries to zero.
- call rtpos ; Position cursor.
- mov ax,0
- call nout ; Write the number of retries.
- mov state,'S' ; Set the state to receive initiate.
- send2:
- IF ibmpc
- mov ah,2 ; Position cursor.
- mov bh,0
- mov dx,scrst
- int bios
- ENDIF
- IF Z100
- mov ah,prstr ; Get print string function
- mov dx,offset scrst ; and string to move cursor
- int dos ; Print the string
- ENDIF
- mov ah,prstr ; Be informative.
- mov dx,offset infms2
- int dos
- IF ibmpc
- mov ah,2
- mov dx,scrnp
- mov bh,0
- int bios
- ENDIF
- IF Z100
- mov ah,prstr ; Get print string function
- mov dx,offset scrnp ; and string to move cursor
- int dos ; Print the string
- ENDIF
- mov ax,numpkt
- call nout ; Write the packet number.
- cmp state,'D' ; Are we in the data send state?
- jne send3
- call sdata
- jmp send2
- send3: cmp state,'F' ; Are we in the file send state?
- jne send4
- call sfile ; Call send file.
- jmp send2
- send4: cmp state,'Z' ; Are we in the EOF state?
- jne send5
- call seof
- jmp send2
- send5: cmp state,'S' ; Are we in the send initiate state?
- jne send6
- call sinit
- jmp send2
- send6: cmp state,'B' ; Are we in the eot state?
- jne send7
- call seot
- jmp send2
- send7: cmp state,'C' ; Are we in the send complete state?
- jne send8
- call serrst ; Reset serial port. [14]
- IF ibmpc
- mov ah,2 ; Position cursor.
- mov dx,scrst
- mov bh,0
- int bios
- ENDIF
- IF Z100
- mov ah,prstr ; Get print string function
- mov dx,offset scrst ; and string to move cursor
- int dos ; Print the string
- ENDIF
- mov ah,prstr
- mov dx,offset infms3 ; Plus a little cuteness.
- cmp cxzflg,0 ; Completed or interrupted? [20b]
- je snd71 ; Ended normally. [20b]
- mov dx,offset infms6 ; Say was interrupted. [20b]
- snd71: int dos ; New label. [20b]
- cmp belflg,0 ; Bell desired? [17a]
- je sendnb ; [17a]
- mov dx,offset ender ; Ring them bells. [4]
- int dos ; [4]
- sendnb: ; [17a -- new label]
- IF ibmpc
- mov ah,2
- mov dx,scrrpr
- mov bh,0
- int bios
- ENDIF
- IF Z100
- mov ah,prstr ; Get print string function
- mov dx,offset scrrpr ; and string to move cursor
- int dos ; Print the string
- ENDIF
- jmp rskp
- send8: call serrst ; Reset serial port. [14]
- IF ibmpc
- mov ah,2 ; Position cursor.
- mov dx,scrst
- mov bh,0
- int bios
- ENDIF
- IF Z100
- mov ah,prstr ; Get print string function
- mov dx,offset scrst ; and string to move cursor
- int dos ; Print the string
- ENDIF
- mov ah,prstr
- mov dx,offset infms4 ; Plus a little cuteness.
- int dos
- cmp belflg,0 ; Bell desired? [17a]
- je send9 ; No. [17a]
- mov dx,offset ender ; Ring them bells. [4]
- int dos ; [4]
- send9:
- IF ibmpc
- mov ah,2
- mov dx,scrrpr
- mov bh,0
- int bios
- ENDIF
- IF Z100
- mov ah,prstr ; Get print string function
- mov dx,offset scrrpr ; and string to move cursor
- int dos ; Print the string
- ENDIF
- jmp rskp
- SEND ENDP
-
-
- ; Send routines
-
- ; Send initiate
-
-
- SINIT PROC NEAR
- cmp numtry,imxtry ; Have we reached the maximum number of tries?
- jl sinit2
- call erpos
- mov dx,offset erms14
- mov ah,prstr
- int dos ; Print an error message.
- jmp abort ; Change the state to abort.
- sinit2: inc numtry ; Save the updated number of tries.
- mov bx,offset data ; Get a pointer to our data block.
- call rpar ; Set up the parameter information.
- xchg ah,al
- mov ah,0
- mov argbk1,ax ; Save the number of arguments.
- mov ax,numpkt ; Get the packet number.
- mov argblk,ax
- mov ah,'S' ; Send initiate packet.
- call spack ; Send the packet.
- jmp abort
- call rpack ; Get a packet.
- jmp r ; Trashed packet don't change state, retry.
- cmp ah,'Y' ; ACK?
- jne sinit3 ; If not try next.
- mov ax,pktnum ; Get the packet number.
- cmp ax,argblk ; Is it the right packet number?
- je sini22
- ret ; If not try again.
- sini22: inc ax ; Increment the packet number.
- and ax,3FH ; Turn off the two high order bits.
- mov pktnum,ax ; Save modulo 64 of the number.
- inc numpkt ; Increment the number of packets.
- mov ax,argbk1 ; Get the number of pieces of data.
- mov bx,offset data ; Pointer to the data.
- call spar ; Read in the data.
- mov ah,numtry ; Get the number of tries.
- mov oldtry,ah ; Save it.
- mov numtry,0 ; Reset the number of tries.
- mov state,'F' ; Set the state to file send.
- call getfil ; Open the file.
- jmp abort ; Something is wrong, die.
- ret
- sinit3: cmp ah,'N' ; NAK?
- jne sinit4 ; If not see if its an error.
- call rtpos ; Position cursor.
- inc numrtr ; Increment the number of retries
- mov ax,numrtr
- call nout ; Write the number of retries.
- ; mov ax,pktnum ; Get the present packet number. [18 start]
- ; inc ax ; Increment.
- ; cmp ax,argblk ; Get the packet's number.
- ; je sini32
- ; ret ; If not assume its for this packet, go again.
- ;sini32: mov numtry,0 ; Reset number of tries.
- ; mov state,'F' ; Set the state to file send. [18 end]
- ret
- sinit4: cmp ah,'E' ; Is it an error packet.
- jne sinit5
- call error
- sinit5: jmp abort
- SINIT ENDP
-
-
-
- ; Send file header
-
- SFILE PROC NEAR
- cmp numtry,maxtry ; Have we reached the maximum number of tries?
- jl sfile1
- call erpos
- mov dx,offset erms14
- mov ah,prstr
- int dos ; Print an error message.
- jmp abort ; Change the state to abort.
- sfile1: inc numtry ; Increment it.
- mov cxzflg,0 ; Clear ^X,^Z flag. [20b]
- mov datptr,offset data ; Get a pointer to our data block.
- mov bx,offset fcb+1 ; Pointer to file name in FCB.
- mov fcbptr,bx ; Save position in FCB.
- mov cl,0 ; Counter for chars in file name.
- mov ch,0 ; Counter for number of chars in FCB.
- sfil11: cmp ch,8H ; Ninth char?
- jne sfil12
- mov ah,'.'
- mov bx,datptr
- mov [bx],ah ; Put dot in data packet.
- inc bx
- mov datptr,bx ; Save new position in data packet.
- inc cl
- sfil12: inc ch
- cmp ch,0CH ; Twelve?
- jns sfil13
- mov bx,fcbptr
- mov ah,[bx] ; Get char of filename.
- inc bx
- mov fcbptr,bx ; Save position in FCB.
- cmp ah,'!' ; Is it a good char?
- jl sfil11 ; If not, get the next.
- mov bx,datptr
- mov [bx],ah ; Put char in data buffer.
- inc cl ; Increment counter.
- inc bx
- mov datptr,bx ; Save new position.
- jmp sfil11 ; Get another char.
- sfil13: mov ch,0
- mov argbk1,cx ; Save number of char in filename.
- mov bx,datptr
- mov ah,'$'
- mov [bx],ah ; Put dollar sign for printing.
- call clrfln
- mov ah,prstr
- mov dx,offset data ; Print file name.
- int dos
-
- mov ax,pktnum ; Get the packet number.
- mov argblk,ax
- mov ah,'F' ; File header packet.
- call spack ; Send the packet.
- jmp abort
- call rpack ; Get a packet.
- jmp r ; Trashed packet don't change state, retry.
- cmp ah,'Y' ; ACK?
- jne sfile2 ; If not try next.
- mov ax,pktnum ; Get the packet number.
- cmp ax,argblk
- je sfil14
- ret ; If not hold out for the right one.
- sfil14: inc ax ; Increment the packet number.
- and ax,3FH ; Turn off the two high order bits.
- mov pktnum,ax ; Save modulo 64 of the number.
- inc numpkt ; Increment the number of packets.
- mov ah,numtry ; Get the number of tries.
- mov oldtry,ah ; Save it.
- mov numtry,0 ; Reset the number of tries.
-
- sfil15: mov ah,0 ; Get a zero.
- mov bx,offset fcb
- add bx,20H
- mov [bx],ah ; Set the record number to zero.
- mov eoflag,ah ; Indicate not EOF.
- mov ah,0FFH
- mov filflg,ah ; Indicate file buffer empty.
- call gtchr
- jmp sfil16 ; Error go see if its EOF.
- jmp sfil17 ; Got the chars, proceed.
- sfil16: cmp ah,0FFH ; Is it EOF?
- je sfl161
- jmp abort ; If not give up.
- sfl161: mov ah,'Z' ; Set the state to EOF.
- mov state,ah
- ret
- sfil17: mov siz,ax
-
- mov state,'D' ; Set the state to data send.
- ret
- sfile2: cmp ah,'N' ; NAK?
- jne sfile3 ; Try if error packet.
- call rtpos ; Position cursor.
- inc numrtr ; Increment the number of retries
- mov ax,numrtr
- call nout ; Write the number of retries.
- mov ax,pktnum ; Get the present packet number.
- inc ax ; Increment.
- and ax,03FH ; Account for wraparound. [18]
- cmp ax,argblk ; Is the packet's number one more than now?
- jz sfil14 ; Just as good as a ACK; go to the ACK code.
- ret ; If not go try again.
- sfile3: cmp ah,'E' ; Is it an error packet.
- jne sfile4
- call error
- sfile4: jmp abort
- SFILE ENDP
-
-
- ; Send data
-
- SDATA PROC NEAR
- cmp cxzflg,0 ; Have we seen ^X or ^Z? [20b]
- je sdata0 ; Nope, just continue. [20b]
- mov state,'Z' ; Else, abort sending the file. [20b]
- ret
- sdata0: cmp numtry,maxtry ; Have we reached the maximum number of tries?
- jl sdata1
- call erpos
- mov dx,offset erms14
- mov ah,prstr
- int dos ; Print an error message.
- jmp abort ; Change the state to abort.
- sdata1: inc numtry ; Increment it.
- mov datptr,offset data ; Get a pointer to our data block.
- mov cbfptr,offset filbuf ; Pointer to chars to be sent.
- mov cx,1 ; First char.
- sdat11: mov bx,cbfptr
- mov ah,[bx]
- inc cbfptr
- mov bx,datptr
- mov [bx],ah ; Put the char in the data packet.
- inc datptr ; Save position in data packet.
- inc cx ; Increment the count.
- cmp cx,siz ; Have we transfered that many?
- jle sdat11 ; If not get another.
- mov ax,siz ; Number of char in char buffer.
- mov argbk1,ax
- mov ax,pktnum ; Get the packet number.
- mov argblk,ax
- mov ah,'D' ; Data packet.
- call spack ; Send the packet.
- jmp abort
- call rpack ; Get a packet.
- jmp r ; Trashed packet don't change state, retry.
- cmp ah,'Y' ; ACK?
- jne sdata2 ; If not try next.
- mov ax,pktnum ; Get the packet number.
- cmp ax,argblk ; Is it the right packet number?
- jz sdat12
- ret ; If not hold out for the right one.
- sdat12: inc ax ; Increment the packet number.
- and ax,3FH ; Turn off the two high order bits.
- mov pktnum,ax ; Save modulo 64 of the number.
- inc numpkt ; Increment the number of packets.
- mov ah,numtry ; Get the number of tries.
- mov oldtry,ah ; Save it.
- mov numtry,0 ; Reset the number of tries.
- cmp argbk1,1 ; Does the ACK contain data? [20b]
- jne sdt12x ; Nope, so continue. [20b]
- mov bx,offset data ; If yes, check the data field. [20b]
- mov ah,[bx] ; Pick it up. [20b]
- cmp ah,'X' ; Other side requests ^X? [20b]
- jne sdt12y ; Nope. [20b]
- jmp sdt12z ; And leave. [20b]
- sdt12y: cmp ah,'Z' ; Other side requests ^Z? [20b]
- jne sdt12x ; Nope. [20b]
- sdt12z: mov cxzflg,ah ; Yes remember it. [20b]
- mov state,'Z' ; Abort sending file(s). [20b]
- ret
- sdt12x: call gtchr
- jmp sdat13 ; Error go see if its EOF.
- mov siz,ax ; Save the size of the data gotten.
- ret
-
- sdat13: cmp ah,0FFH ; Is it EOF?
- je sdt131
- jmp abort ; If not give up.
-
- sdt131: mov state,'Z' ; Set the state to EOF.
- ret
- sdata2: cmp ah,'N' ; NAK?
- jne sdata3 ; See if is an error packet.
- call rtpos ; Position cursor.
- inc numrtr ; Increment the number of retries
- mov ax,numrtr
- call nout ; Write the number of retries.
- mov ax,pktnum ; Get the present packet number.
- inc ax ; Increment.
- and ax,03FH ; Account for wraparound. [18]
- cmp ax,argblk ; Is the packet's number one more than now?
- jz sdat12 ; Just as good as ACK; goto ACK code.
- ret ; If not go try again.
- sdata3: cmp ah,'E' ; Is it an error packet.
- jne sdata4
- call error
- sdata4: jmp abort
- SDATA ENDP
-
-
- ; Send EOF
-
- SEOF PROC NEAR
- cmp numtry,maxtry ; Have we reached the maximum number of tries?
- jl seof1
- call erpos ; Position cursor.
- mov dx,offset erms14
- mov ah,prstr
- int dos ; Print an error message.
- jmp abort ; Change the state to abort.
- seof1: inc numtry ; Increment it.
- mov ax,pktnum ; Get the packet number.
- mov argblk,ax
- mov argbk1,0 ; No data.
- cmp cxzflg,0 ; Seen a ^X or ^Z? [20b]
- je seof11 ; Nope, send normal EOF packet. [20b]
- mov bx,offset data ; Get data area of packet.
- mov ah,'D' ; Use "D" for discard. [20b]
- mov [bx],ah ; And add it to the packet. [20b]
- mov argbk1,1 ; Set data size to 1. [20b]
- seof11: mov ah,'Z' ; EOF packet.
- call spack ; Send the packet.
- jmp abort
- call rpack ; Get a packet.
- jmp r ; Trashed packet don't change state, retry.
- cmp ah,'Y' ; ACK?
- jne seof2 ; If not try next.
- mov ax,pktnum ; Get the packet number.
- cmp ax,argblk ; Is it the right packet number?
- jz seof12
- ret ; If not hold out for the right one.
- seof12: inc ax ; Increment the packet number.
- and ax,3FH ; Turn off the two high order bits.
- mov pktnum,ax ; Save modulo 64 of the number.
- inc numpkt ; Increment the number of packets.
- mov ah,numtry ; Get the number of tries.
- mov oldtry,ah ; Save it.
- mov numtry,0 ; Reset the number of tries.
- mov ah,closf ; Close the file.
- mov dx,offset fcb
- int dos
- call gtnfil ; Get the next file.
- jmp seof13 ; No more.
- mov state,'F' ; Set the state to file send.
- cmp cxzflg,'X' ; Control-X seen? [20b]
- jne seof14
- call cxmsg ; Clear out the interrupt msg. [20b]
- seof14: mov cxzflg,0 ; Reset the flag. [20b]
- ret
- seof13: mov state,'B' ; Set the state to EOT.
- ret
- seof2: cmp ah,'N' ; NAK?
- jne seof3 ; Try and see if its an error packet.
- call rtpos ; Position cursor.
- inc numrtr ; Increment the number of retries
- mov ax,numrtr
- call nout ; Write the number of retries.
- mov ax,pktnum ; Get the present packet number.
- inc ax ; Increment.
- and ax,03FH ; Account for wraparound. [18]
- cmp ax,argblk ; Is the packet's number one more than now?
- jz seof12 ; Just as good as a ACK; go to the ACK code.
- ret ; If not go try again.
- seof3: cmp ah,'E' ; Is it an error packet?
- jne seof4
- call error
- seof4: jmp abort
- SEOF ENDP
-
-
- ; Send EOT
-
- SEOT PROC NEAR
- cmp numtry,maxtry ; Have we reached the maximum number of tries?
- jl seot1
- call erpos ; Position cursor.
- mov dx,offset erms14
- mov ah,prstr
- int dos ; Print an error message.
- jmp abort ; Change the state to abort.
- seot1: inc numtry ; Increment it.
- mov ax,pktnum ; Get the packet number.
- mov argblk,ax
- mov argbk1,0 ; No data.
- mov ah,'B' ; EOF packet.
- call spack ; Send the packet.
- jmp abort
- call rpack ; Get a packet.
- jmp r ; Trashed packet don't change state, retry.
- cmp ah,'Y' ; ACK?
- jne seot2 ; If not try next.
- mov ax,pktnum ; Get the packet number.
- cmp ax,argblk ; Is it the right packet number?
- jz seot12
- ret ; If not hold out for the right one.
- seot12: inc ax ; Increment the packet number.
- and ax,3FH ; Turn off the two high order bits.
- mov pktnum,ax ; Save modulo 64 of the number.
- inc numpkt ; Increment the number of packets.
- mov ah,numtry ; Get the number of tries.
- mov oldtry,ah ; Save it.
- mov numtry,0 ; Reset the number of tries.
- mov state,'C' ; Set the state to file send.
- ret
- seot2: cmp ah,'N' ; NAK?
- jne seot3 ; Is it error.
- call rtpos ; Position cursor.
- inc numrtr ; Increment the number of retries
- mov ax,numrtr
- call nout ; Write the number of retries.
- mov ax,pktnum ; Get the present packet number.
- inc ax ; Increment.
- and ax,03FH ; Account for wraparound. [18]
- cmp ax,argblk ; Is the packet's number one more than now?
- jz seot12 ; Just as good as a ACK; go to the ACK code.
- ret ; If not go try again.
- seot3: cmp ah,'E' ; Is it an error packet.
- jne seot4
- call error
- seot4: jmp abort
- SEOT ENDP
-
-
- ; Here is the bulk of the file I/O. Good luck.
- ; File routines
-
- ; Output the chars in a packet.
-
- FILEIO PROC NEAR
-
- ptchr: mov temp1,ax ; Save the size.
- mov bx,offset data ; Beginning of received packet data.
- mov outpnt,bx ; Remember where we are.
- mov ch,rquote ; Quote char.
- ptchr1: dec temp1 ; Decrement # of chars in packet.
- jnl pt1
- jmp rskp ; Return successfully if done.
- pt1: dec chrcnt ; Decrement number of chars in dta.
- jns ptchr2 ; Continue if space left.
- call outbuf ; Output it if full.
- jmp r ; Error return if disk is full.
- ptchr2: mov bx,outpnt ; Get position in output buffer.
- mov ah,[bx] ; Grab a char.
- inc bx
- mov outpnt,bx ; and bump pointer.
- cmp ah,ch ; Is it the quote char?
- jne ptchr4 ; If not proceed.
- mov ah,[bx] ; Get the quoted character
- inc bx
- mov outpnt,bx ; and bump pointer.
- dec temp1 ; Decrement # of chars in packet.
- mov dh,ah ; Save the char.
- and ah,80H ; Turn off all but the parity bit.
- mov dl,ah ; Save the parity bit.
- mov ah,dh ; Get the char.
- and ah,7FH ; Turn off the parity bit.
- cmp ah,ch ; Is it the quote char?
- jz ptchr3 ; If so just go write it out.
- mov ah,dh ; Get the char.
- add ah,40H ; Make it a control char again.
- and ah,7FH ; Modulo 128.
- ptchr3: or ah,dl ; Or in the parity bit.
- ptchr4: mov bx,bufpnt ; Destination buffer.
- mov [bx],ah ; Store it.
- inc bx
- mov bufpnt,bx ; Update the pointer
- jmp ptchr1 ; and loop to next char.
-
-
- ; output the buffer, reset bufpnt and chrcnt
-
- outbuf: push bx
- mov ah,writef ; The write code.
- mov dx,offset fcb
- int dos ; Write the record.
- pop bx
- cmp al,0 ; Successful.
- jz outbf1
- push ax ; Remember the return code. [20d]
- call abfil ; Fix things up before aborting. [20d]
- pop ax ; Retrive return code. [20d]
- cmp al,01
- jz outbf0
- call erpos
- mov ah,prstr
- mov dx,offset erms17 ; Record length exceeds dta.
- int dos
- ret
- outbf0: call erpos
- mov ah,prstr ; Tell about it.
- mov dx,offset erms11 ; Disk full error.
- int dos
- ret
- outbf1: mov bx,offset buff ; Addr for beginning.
- mov bufpnt,bx ; Store addr for beginning.
- mov ax,bufsiz-1 ; Buffer size.
- mov chrcnt,ax ; Number of chars left.
- jmp rskp
-
- ; Tidy up before aborting. [20d]
- ABFIL PROC NEAR
- mov ah,closf ; Close the file.
- mov dx,offset fcb
- int dos
- cmp abfflg,1 ; Delete what got across or keep it?
- jne abfil0 ; Nope, keep it.
- mov ah,delf ; Delete it.
- mov dx,offset fcb
- int dos
- abfil0: mov bx,offset erms10 ; Text of message to send.
- call errpack ; Send an error packet.
- ret
- ABFIL ENDP
-
- ; General routine for sending an error packet. Register BX should
- ; point to the text of the message being sent in the packet. [20f]
-
- ERRPACK PROC NEAR
- mov di,offset data ; Where to put the message.
- mov al,0
- errp1: mov ah,[bx]
- cmp ah,'$' ; At end of message?
- je errp2
- inc al ; Remember number of chars in msg.
- mov [di],ah
- inc bx
- inc di
- jmp errp1
- errp2: mov ah,0
- mov argbk1,ax
- mov ah,'E' ; And send an error packet.
- call spack
- ret ; Return if succeed or fail.
- nop
- nop
- ret
- ERRPACK ENDP
-
- ; Get the chars from the file.
-
- gtchr: mov ch,squote ; Keep quote char in c.
- mov ah,filflg ; Get the file flag.
- cmp ah,0 ; Is there anything in the DMA?
- jz gtchr0 ; Yup, proceed.
- mov cl,0 ; No chars yet.
- call inbuf
- jmp gtceof ; No more chars, go return EOF.
- gtchr0: mov al,spsiz ; Get the maximum packet size.
- sub al,5 ; Subtract the overhead.
- mov ah,0
- mov temp1,ax ; Number of chars we're to get.
- mov bx,offset filbuf ; Where to put the data.
- mov cbfptr,bx ; Remember where we are.
- mov cl,0 ; No chars.
- gtchr1: dec temp1 ; Decrement the number of chars left.
- jns gtchr2 ; Go on if there is more than one left.
- mov al,cl ; Return the count in A.
- mov ah,0
- jmp rskp
- gtchr2: mov ax,chrcnt
- dec ax
- jl gtchr3
- mov chrcnt,ax
- jmp gtchr4
- gtchr3: call inbuf ; Get another buffer full.
- jmp gtceof
- cmp chrcnt,0
- jne gtchr4
- sub cl,2 ; Don't count controllified Z.
- mov al,cl
- mov ah,0
- jmp rskp
- gtchr4: mov bx,bufpnt ; Position in DMA.
- mov ah,[bx] ; Get a char from the file.
- inc bx
- mov bufpnt,bx
- mov dh,ah ; Save the char.
- and ah,80H ; Turn off all but parity.
- mov dl,ah ; Save the parity bit.
- mov ah,dh ; Restore the char.
- and ah,7FH ; Turn off the parity.
- cmp ah,' ' ; Compare to a space.
- jl gtchr5 ; If less then its a control char, handle it.
- cmp ah,del ; Is the char a delete?
- jz gtchr5 ; Go quote it.
- cmp ah,ch ; Is it the quote char?
- jne gtchr8 ; If not proceed.
- dec temp1 ; Decrement the char total remaining.
- mov bx,cbfptr ; Position in character buffer.
- mov [bx],ah ; Put the char in the buffer.
- inc bx
- mov cbfptr,bx
- inc cl ; Increment the char count.
- jmp gtchr8
- gtchr5: or ah,dl ; Turn on the parity bit.
- cmp ah,('Z'-100O) ; Is it a ^Z?
- jne gtchr7 ; If not just proceed.
- mov ah,eoflag ; EOF flag set?
- cmp ah,0
- jz gtchr6 ; If not just go on.
- mov bx,bufpnt
- mov ax,chrcnt
- mov dh,al ; Get number of chars left in DMA.
- gtch51: dec dh
- mov ah,dh
- jns gtch52 ; Any chars left?
- mov chrcnt,0 ; If not, say so.
- mov al,cl ; Return the count in A.
- mov ah,0
- jmp rskp
- gtch52: mov ah,[bx] ; Get the next char.
- inc bx ; Move the pointer.
- cmp ah,('Z'-100O) ; Is it a ^Z?
- jz gtch51 ; If so see if they rest are.
-
- gtchr6: mov ah,('Z'-100O) ; Restore the ^Z.
- gtchr7: xchg ah,al
- mov ah,0
- mov temp2,ax ; Save the char.
- dec temp1 ; Decrement char counter.
- mov bx,cbfptr ; Position in character buffer.
- mov [bx],ch ; Put the quote in the buffer.
- inc bx
- mov cbfptr,bx
- inc cl ; Increment the char count.
- mov ax,temp2 ; Get the control char back.
- xchg al,ah
- add ah,40H ; Make the non-control.
- and ah,7fH ; Modulo 200 octal.
- gtchr8: mov bx,cbfptr ; Position in character buffer.
- or ah,dl ; Or in the parity bit.
- mov [bx],ah ; Put the char in the buffer.
- inc bx
- mov cbfptr,bx
- inc cl ; Increment the char count.
- jmp gtchr1 ; Go around again.
-
- gtceof: cmp cl,0 ; Had we gotten any data?
- je gteof0 ; Nope.
- mov al,cl
- mov ah,0
- jmp rskp
- gteof0: mov ah,0FFH ; Get a minus one.
- ret
-
-
- inbuf: mov ah,eoflag ; Have we reached the end?
- cmp ah,0
- jz inbuf0
- ret ; Return if set.
- inbuf0: push bx
- push cx
- mov bx,offset buff ; Set the r/w buffer pointer.
- mov bufpnt,bx
- mov ah,readf ; Read a record.
- mov dx,offset fcb
- int dos
- mov cx,filsiz
- cmp cx,0 ; Check for 128 chars or less left.
- jne inbuf1 ; Still have data left.
- mov ax,ds
- mov es,ax
- mov si,offset filsiz+2
- mov di,offset bufhex
- cmps filsiz+2,es:bufhex
- ja inbuf1 ; More than 128 chars.
- mov eoflag,0FFH ; Set End-of-file.
- mov cx,filsiz+2
- mov chrcnt,cx ; Return proper number of chars.
- mov filflg,0 ; Buffer not empty.
- pop cx
- pop bx
- jmp rskp
- inbuf1: sub filsiz+2,80H ; Sent another 128 chars.
- sbb filsiz,0 ; Account for the doubleword.
- mov al,80H ; Use as counter for number of chars read.
- pop cx
- pop bx
- cmp filflg,0 ; Ever used DMS?
- jnz inbf21 ; Nope, then don't change count.
- dec al ; Fix boundary error.
- inbf21: mov ah,0 ; Zero the flag (buffer not empty).
- mov chrcnt,ax ; Number of chars read from file.
- mov filflg,0 ; Buffer not empty.
- jmp rskp
-
- getfil: mov ah,0FFH
- mov filflg,ah ; Nothing in the DMA.
- mov ax,0
- mov eoflag,ah ; Not the end of file.
- mov bx,offset fcb+0CH
- mov [bx],ax ; Zero the current block number.
- mov bx,offset fcb+0EH
- mov [bx],ax ; Ditto for Lrecl.
- mov bx,offset fcb+20H
- mov [bx],ah ; Zero the current record (of block).
- inc bx
- mov [bx],ax ; Same for record (of file).
- mov bx,offset fcb+23H
- mov [bx],ax
- mov ah,openf ; Open the file.
- mov dx,offset fcb
- int dos
- mov bx,offset fcb+18 ; File size in bytes (hi order word).
- mov di,offset filsiz ; Where to put the info.
- mov ax,[bx]
- mov [di],ax
- mov bx,offset fcb+16 ; Lo order word.
- mov ax,[bx]
- mov 2[di],ax
- sub filsiz+2,1 ; Don't count the ^Z.
- sbb filsiz,0
- jmp rskp
-
-
- gtnfil: cmp cxzflg,'Z' ; Did we have a ^Z? [20b]
- je gtn5 ; If yes, we're done sending files. [20b]
- cmp wldflg,0 ; Was there a "*"? [7 start]
- je gtn5 ; Nope.
- mov bx,offset cpfcb ; Get FCB from last check for file.
- mov di,offset fcb ; Copy to FCB.
- mov cl,37 ; Size of FCB.
- call fcbcpy
- gtn2: mov ah,snext
- mov dx,offset fcb ; More files?
- int dos
- cmp al,0FFH
- je gtn5
- mov bx,offset fcb
- mov di,offset cpfcb
- mov cl,37
- call fcbcpy ; Copy from FCB.
- mov di,offset fcb+1 ; Get name of next file to send.
- mov bx,offset buff+1
- mov cl,11
- call fcbcpy
- call getfil ; Initialize
- jmp r
- jmp rskp
- gtn5: mov wldflg,0 ; Reset wild card flag.
- ret ; [7 end]
-
-
- ; Get the file name (including host to micro translation)
-
- gofil: mov bx,offset data ; Get the address of the file name.
- mov datptr,bx ; Store the address.
- mov bx,offset fcb+1 ; Address of the FCB.
- mov fcbptr,bx ; Save it.
- mov ax,0
- mov temp1,ax ; Initialize the char count.
- mov temp2,ax
- mov si,offset fcb
- mov [si],ah ; Set the drive to default to current.
- mov ch,' '
- gofil1: mov [bx],ch ; Blank the FCB.
- inc bx
- inc ah
- cmp ah,0BH ; Twelve?
- jl gofil1
- gofil2: mov bx,datptr ; Get the NAME field.
- mov ah,[bx]
- inc bx
- mov datptr,bx
- cmp ah,'.' ; Seperator?
- jne gofil3
- mov bx,offset fcb+9H
- mov fcbptr,bx
- mov ax,temp1
- mov temp2,ax
- mov temp1,9H
- jmp gofil6
- gofil3: cmp ah,0 ; Trailing null?
- jz gofil7 ; Then we're done.
- mov bx,fcbptr
- mov [bx],ah
- inc bx
- mov fcbptr,bx
- mov ax,temp1 ; Get the char count.
- inc ax
- mov temp1,ax
- cmp ax,8H ; Are we finished with this field?
- jl gofil2
- gofil4: mov temp2,ax
- mov bx,datptr
- mov ah,[bx]
- inc bx
- mov datptr,bx
- cmp ah,0
- jz gofil7
- cmp ah,'.' ; Is this the terminator?
- jne gofil4 ; Go until we find it.
- gofil6: mov bx,datptr ; Get the TYPE field.
- mov ah,[bx]
- inc bx
- mov datptr,bx
- cmp ah,0 ; Trailing null?
- jz gofil7 ; Then we're done.
- mov bx,fcbptr
- mov [bx],ah
- inc bx
- mov fcbptr,bx
- inc temp1 ; Increment char count.
- cmp temp1,0CH ; Are we finished with this field?
- jl gofil6
- gofil7: mov bx,datptr
- mov ah,'$'
- mov [bx],ah ; Put in a dollar sign for printing.
- call clrfln
- mov ah,prstr ; Print the file name.
- mov dx,offset data
- int dos
- mov ah,flwflg ; Is file warning on?
- cmp ah,0
- jnz gf7x
- jmp gofil9 ; If not, just proceed.
- gf7x: mov ah,openf ; See if the file exists.
- mov dx,offset fcb
- int dos
- cmp al,0FFH ; Does it exist?
- jnz gf8x
- jmp gofil9 ; If not create it.
- gf8x:
- IF ibmpc
- mov ah,2 ; Position cursor.
- mov dx,scrfr
- mov bh,0
- int bios
- ENDIF
- IF Z100
- mov ah,prstr ; Get print string function
- mov dx,offset scrfr ; and string to move cursor
- int dos ; Print the string
- ENDIF
- mov ah,prstr ; Inform the user we are renaming the file.
- mov dx,offset infms5
- int dos
- mov ax,temp2 ; Get the number of chars in the file name.
- cmp ax,0
- jne gofil8
- mov ax,temp1
- mov temp2,ax
- gofil8: mov ch,0
- mov cl,al
- mov al,0 ; Says if first field is full.
- cmp cl,9H ; Is the first field full?
- jne gofl81
- mov al,0FFH ; Set a flag saying so.
- dec cl
- gofl81: mov bx,offset fcb ; Get the FCB.
- add bx,cx ; Add in the character number.
- mov ah,'&'
- mov [bx],ah ; Replace the char with an ampersand.
- push ax
- push bx
- mov ah,openf ; See if the file exists.
- mov dx,offset fcb
- int dos
- pop bx
- cmp al,0FFH ; Does it exist?
- pop ax
- jz gofl89 ; If not create it.
- cmp al,0 ; Get the flag.
- jz gofl83
- dec cl ; Decrement the number of chars.
- cmp cl,0
- jz gofl88 ; If no more, die.
- jmp gofl81
- gofl83: inc cl ; Increment the number of chars.
- cmp cl,9H ; Are we to the end?
- jl gofl81 ; If not try again ; else fail.
-
- gofl88: call erpos ; Position cursor.
- mov ah,prstr ; Tell the user that we can't rename it.
- mov dx,offset ermes4
- int dos
- mov bx,dx ; Tell host can't rename. [20f]
- call errpack ; Send error packet before abort. [20f]
- ret
-
- gofl89: mov bx,offset fcb+0CH ; Point past the end of the file name.
- mov dh,[bx] ; Save the present contents.
- mov ah,'$'
- mov [bx],ah ; Put in a dollar sign.
- push dx
- mov ah,prstr ; Print the file name.
- mov dx,offset fcb+1
- int dos
- pop dx
- mov bx,offset fcb+0CH ; Restore over the dollar sign.
- mov [bx],dh
- gofil9: mov ah,delf ; Delete the file if it exists.
- mov dx,offset fcb
- int dos
- mov ax,0
- mov si,offset fcb+0CH
- mov [si],ax ; Zero current block.
- mov si,offset fcb+0EH
- mov [si],ax ; Same for Lrecl.
- mov si,offset fcb+20H
- mov [si],ah ; Zero the current record (within block).
- inc si
- mov [si],ax ; Zero record (within file).
- mov si,offset fcb+23H
- mov [si],ax
- mov ah,makef ; Now create it.
- mov dx,offset fcb
- int dos
- cmp al,0FFH ; Is the disk full?
- je gf9x
- jmp rskp
- gf9x: call erpos ; Position cursor.
- mov ah,prstr ; If so tell the user.
- mov dx,offset erms11
- int dos
- ret
-
- FILEIO ENDP
-
-
- ; Packet routines
-
- ; Send_Packet
- ; This routine assembles a packet from the arguments given and sends it
- ; to the host.
- ;
- ; Expects the following:
- ; AH - Type of packet (D,Y,N,S,R,E,F,Z,T)
- ; ARGBLK - Packet sequence number
- ; ARGBK1 - Number of data characters
- ; Returns: +1 always
-
- SPKT PROC NEAR
-
- spack: push ax ; Save the packet type.
- IF ibmpc
- call clrbuf ; Clear the input buffer. [20e]
- ENDIF
- mov bx,offset packet ; Get address of the send packet.
- mov ah,soh ; Get the start of header char.
- mov [bx],ah ; Put in the packet.
- inc bx ; Point to next char.
- mov ax,argbk1 ; Get the number of data chars.
- xchg ah,al
- add ah,' '+3 ; Real packet character count made printable.
- mov [bx],ah ; Put in the packet.
- inc bx ; Point to next char.
- mov cl,ah ; Start the checksum.
- mov ax,argblk ; Get the packet number.
- xchg ah,al
- add ah,' ' ; Add a space so the number is printable.
- mov [bx],ah ; Put in the packet.
- inc bx ; Point to next char.
- add cl,ah ; Add the packet number to the checksum.
- pop ax ; Get the packet type.
- mov [bx],ah ; Put in the packet.
- inc bx ; Point to next char.
- add cl,ah ; Add the type to the checksum.
- mov dx,argbk1 ; Get the packet size.
- spack2: cmp dx,0 ; Are there any chars of data?
- jz spack3 ; No, finish up.
- dec dx ; Decrement the char count.
- mov ah,[bx] ; Get the next char.
- inc bx ; Point to next char.
- add cl,ah ; Add the char to the checksum.
- cmp ah,0
- jns spack2
- mov hierr,0FFH ; set err flag.
- jmp spack2 ; Go try again.
- spack3: cmp hierr,0
- je sp3x ; Nothing special to do.
- call biterr
- mov hierr,0 ; Reset.
- sp3x: mov ah,cl ; Get the character total.
- mov ch,cl ; Save here too (need 'cl' for shift).
- and ah,0C0H ; Turn off all but the two high order bits.
- mov cl,6
- shr ah,cl ; Shift them into the low order position.
- mov cl,ch
- add ah,cl ; Add it to the old bits.
- and ah,3FH ; Turn off the two high order bits. (MOD 64)
- add ah,' ' ; Add a space so the number is printable.
- mov [bx],ah ; Put in the packet.
- inc bx ; Point to next char.
- mov ah,seol ; Get the EOL the other host wants.
- mov [bx],ah ; Put in the packet.
- inc bx ; Point to next char.
- mov ah,0 ; Get a null.
- mov [bx],ah ; Put in the packet.
- cmp debug,0 ; debug mode.
- je spack4
- inc bx
- mov ah,'$'
- mov [bx],ah
- IF ibmpc
- mov ah,2
- mov dx,scrsp
- mov bh,0
- int bios
- ENDIF
- IF Z100
- mov ah,prstr ; Get print string function
- mov dx,offset scrsp ; and string to move cursor
- int dos ; Print the string
- ENDIF
- mov ah,prstr
- mov dx,offset spmes
- int dos
- mov dx,offset packet
- mov ah,prstr
- int dos ; debug end.
- spack4: call outpkt ; Call the system dependent routine.
- jmp r
- jmp rskp
-
- SPKT ENDP
- ; Write out a packet.
-
- OUTPKT PROC NEAR
- mov dh,spad ; Get the number of padding chars.
- outpk2: dec dh
- cmp dh,0
- jl outpk3 ; If none left proceed.
- mov ah,spadch ; Get the padding char.
- call outchr ; Output it.
- jmp outpk2
- outpk3: mov bx,offset packet ; Point to the packet.
- outlup: mov ah,[bx] ; Get the next character.
- cmp ah,0 ; Is it a null?
- jnz outlp2
- jmp rskp
- outlp2: call outchr ; Output the character.
- jmp r
- inc bx ; Increment the char pointer.
- jmp outlup
- OUTPKT ENDP
-
-
- ;************************System Dependent****************************
- ; Put a char in AH to the port.
- PORT PROC NEAR
- IF ibmpc
- outchr: sub cx,cx ; [14 start]
- mov al,ah ; Parity routine works on AL. [16]
- call dopar ; Set parity appropriately. [10]
- mov ah,al ; Don't overwrite character with status. [16]
- mov dx,mdstat ; Get port status. [19b]
- outch1: in al,dx
- test al,20H ; Transmitter ready?
- jnz outch2 ; Yes
- loop outch1
- jmp r ; Timeout
- outch2: mov al,ah ; Now send it out
- mov dx,mddat ; [19b]
- out dx,al
- jmp rskp ; [14 end]
- ENDIF
- IF Z100
- outchr: mov al,ah ; Yes, get the character into al
- mov cx,0
- call dopar ; Set parity appropriately. [10]
- outch1: call bios_auxout ; Send the character
- jmp rskp
- ENDIF
-
- ;************************System Dependent****************************
- ;
- ; Get a char from the port and return in AH.
-
- inchr:
- IF ibmpc
- call prtchr ; Get character if ready. [14]
- jmp inchr3 ; Got it in AL. [14]
- ENDIF
- IF Z100
- push bx ; Save BX
- mov ah,chr_status ; Get the function
- mov al,chr_sfgs ; And the subfunction
- call bios_auxfunc ; Determine if anything to input
- cmp bl,0 ; Is there?
- jnz inchr3 ; Yes, go get it
- pop bx ; And restore BX
- ENDIF
- mov ah,constat ; Is a char on the console?
- int dos
- cmp al,0
- jz inchr ; If not go look for another char.
- mov ah,conin ; Get the char.
- int dos
- mov ah,al
- cmp ah,cr ; Is it a carriage return?
- je inchr4 ; If yes, then leave.
- cmp ah,'Z'-100O ; Control-Z? [20b]
- je inchr2 ; Yes - flag it. [20b]
- cmp ah,'X'-100O ; Control-X? [20b]
- je inchr2 ; Yes - flag it. [20b]
- jmp inchr ; Wait for some kind of input.
- inchr2: add ah,100O ; Make it printable. [20b]
- mov cxzflg,ah ; Remember what we saw. [20b]
- jmp inchr ; Continue getting input. [20b]
- inchr4: ret
- inchr3:
- IF Z100
- mov ah,chr_read ; Get the function to read
- call bios_auxfunc ; Get a character
- pop bx ; Restore BX
- ENDIF
- mov ah,al
- cmp parflg,parnon ; Is the parity none? [10]
- je inchr5 ; We're done. [10]
- and ah,7FH ; Turn off the parity bit.
- inchr5: jmp rskp
-
- ; Set parity for character in Register AL.
-
- dopar: cmp parflg,parnon ; No parity? [10 start]
- je parret ; Just return
- cmp parflg,parevn ; Even parity?
- jne dopar0
- and al,07FH ; Strip parity.
- jpe parret ; Already even, leave it.
- or al,080H ; Make it even parity.
- jmp parret
- dopar0: cmp parflg,parmrk ; Mark parity?
- jne dopar1
- or al,080H ; Turn on the parity bit.
- jmp parret
- dopar1: cmp parflg,parodd ; Odd parity?
- jne dopar2
- and al,07FH ; Strip parity.
- jpo parret ; Already odd, leave it.
- or al,080H ; Make it odd parity.
- jmp parret
- dopar2: and al,07FH ; Space parity - turn off parity bit.
- parret: ret ; [10 end]
- PORT ENDP
-
- ; Clear the input buffer before sending a packet. [20e]
- IF ibmpc
- CLRBUF PROC NEAR
- lea ax,cs:source ; Initialize the pointers
- mov cs:srcpnt,ax
- mov cs:savesi,ax
- mov cs:count,0
- mov di,cs:srcpnt ; Where to store bytes
- mov ax,cs ; Ready ES for string operations
- mov es,ax
- mov si,0 ; Where to fetch bytes
- ret
- CLRBUF ENDP
- ENDIF
-
- ; Receive_Packet
- ; This routine waits for a packet arrive from the host. It reads
- ; chars until it finds a SOH.
-
- RPACK PROC NEAR
- IF ibmpc
- mov ah,2
- mov dx,scrst ; Position cursor.
- mov bh,0
- int bios
- ENDIF
- IF Z100
- mov ah,prstr ; Get the function to print string
- mov dx,offset scrst ; Get the string address
- int dos ; Position the cursor
- ENDIF
- mov ah,prstr
- mov dx,offset infms0
- int dos
- rpack5: call inpkt ; Read up to a carriage return.
- jmp r ; Return bad.
- rpack0: call getchr ; Get a character.
- jmp r ; Hit the carriage return, return bad.
- cmp ah,soh ; Is the char the start of header char?
- jne rpack0 ; No, go until it is.
- rpack1: call getchr ; Get a character.
- jmp r ; Hit the carriage return, return bad.
- cmp ah,soh ; Is the char the start of header char?
- jz rpack1 ; Yes, then go start over.
- mov cl,ah ; Start the checksum.
- sub ah,' '+3 ; Get the real data count.
- mov dh,ah ; Save it for later.
- mov al,ah ; Swap halves.
- mov ah,0
- mov argbk1,ax ; Save the data count.
- call getchr ; Get a character.
- jmp r ; Hit the carriage return, return bad.
- cmp ah,soh ; Is the char the start of header char?
- jz rpack1 ; Yes, then go start over.
- add cl,ah ; Add it to the checksum.
- sub ah,' ' ; Get the real packet number.
- mov al,ah ; Swap halves.
- mov ah,0
- mov argblk,ax ; Save the packet number.
- call getchr ; Get a character.
- jmp r ; Hit the carriage return, return bad.
- cmp ah,soh ; Is the char the start of header char?
- jz rpack1 ; Yes, then go start over.
- mov temp,ax ; Save the message type. [11]
- add cl,ah ; Add it to the checksum.
- mov bx,offset data ; Point to the data buffer.
- rpack2: dec dh ; Any data characters?
- js rpack3 ; If not go get the checksum.
- call getchr ; Get a character.
- jmp r ; Hit the carriage return, return bad.
- cmp ah,soh ; Is the char the start of header char?
- jz rpack1 ; Yes, then go start over.
- mov [bx],ah ; Put the char into the packet.
- inc bx ; Point to the next character.
- add cl,ah ; Add it to the checksum.
- jmp rpack2 ; Go get another.
- rpack3: call getchr ; Get a character.
- jmp r ; Hit the carriage return, return bad.
- cmp ah,soh ; Is the char the start of header char?
- jz rpack1 ; Yes, then go start over.
- sub ah,' ' ; Turn the char back into a number.
- mov dh,cl ; Get the character total.
- and dh,0C0H ; Turn off all but the two high order bits.
- mov ch,cl
- mov cl,6
- shr dh,cl ; Shift them into the low order position.
- mov cl,ch
- add dh,cl ; Add it to the old bits.
- and dh,3FH ; Turn off the two high order bits. (MOD 64)
- cmp dh,ah ; Are they equal?
- jz rpack4 ; If so finish up.
- ret
- rpack4: mov ah,0
- mov [bx],ah ; Put a null at the end of the data.
- mov ax,temp ; Get the type. [11]
- jmp rskp
- RPACK ENDP
-
-
- INPKT PROC NEAR
- mov bl,cxzflg ; Remember original value. [20b]
- mov tmp,bl ; Store it here. [20b]
- mov bx,offset recpkt ; Point to the beginning of the packet.
- mov incnt,0
- inpkt2: call inchr ; Get a character.
- jmp inpkt0 ; Return failure. [20b]
- nop ; Make it three bytes long. [20b]
- mov [bx],ah ; Put the char in the packet.
- inc bx
- inc incnt
- cmp ah,reol ; Is it the EOL char?
- jne inpkt2 ; If not loop for another.
- cmp incnt,1 ; Ignore bare CR. [2 start]
- jne inpkt6
- mov incnt,0
- mov bx,offset recpkt
- jmp inpkt2 ; [2 end]
- inpkt6: cmp ibmflg,0 ; Is this the (dumb) IBM mainframe?
- jz inpkt4 ; If not then proceed.
- inpkt5: cmp state,'S' ; Check if this is the Send-Init packet.
- jz inpkt4 ; If so don't wait for the XON.
- inpkt3: call inchr ; Wait for the turn around char.
- jmp inpkt0 ; Return failure. [20b]
- nop ; Make it three bytes long. [20b]
- cmp ah,xon ; Is it the IBM turn around character?
- jne inpkt3 ; If not, go until it is.
- inpkt4: mov bx,offset recpkt
- mov pktptr,bx ; Save the packet pointer.
- mov bl,tmp ; Get the original value. [20b]
- cmp bl,cxzflg ; Did ^X/^Z flag change? [20b]
- je inpkx ; If not, just return. [20b]
- call intmsg ; Else, say we saw the interrupt. [20b]
- inpkx: jmp rskp ; If so we are done.
- inpkt0: mov bl,tmp ; Get the original value. [20b]
- cmp bl,cxzflg ; Did ^X/^Z flag change? [20b]
- je inpky ; If not, just return failure. [20b]
- call intmsg ; Else, say we saw the interrupt. [20b]
- inpky: jmp r
- INPKT ENDP
-
- GETCHR PROC NEAR
- push bx
- mov bx,pktptr ; Get the packet pointer.
- mov ah,[bx] ; Get the char.
- inc bx
- mov pktptr,bx
- pop bx ; Restore BX.
- cmp ah,reol ; Is it the EOL char?
- jne getcr2 ; If not return retskp.
- ret ; If so return failure.
- getcr2: jmp rskp
- GETCHR ENDP
-
-
- ; This is where we go if we get an error packet. A call to ERROR
- ; positions the cursor and prints the message. A call to ERROR1
- ; just prints a CRLF and then the message. [8]
-
- ERROR PROC NEAR
- mov state,'A' ; Set the state to abort.
- call erpos ; Position the cursor.
- jmp error2
- error1: mov ah,prstr
- mov dx,offset crlf
- int dos
- error2: mov bx,argbk1 ; Get the length of the data.
- add bx,offset data ; Get to the end of the string.
- mov ah,'$' ; Put a dollar sign at the end.
- mov [bx],ah
- mov ah,prstr ; Print the error message.
- mov dx,offset data
- int dos
- ret
- ERROR ENDP
-
- ; LOGOUT - tell remote KERSRV to logout.
-
- LOGOUT PROC NEAR ; [8 start]
- mov ah,cmcfm
- call comnd ; Get a confirm.
- jmp r
- call logo
- jmp rskp ; Go get another command whether we ....
- jmp rskp ; .... succeed or fail.
- LOGOUT ENDP
-
- LOGO PROC NEAR
- mov numtry,0 ; Initialize count.
- call serini ; Initialize port. [14]
- logo1: mov ah,numtry
- cmp ah,maxtry ; Too many times?
- js logo3 ; No, try it.
- logo2: mov ah,prstr
- mov dx,offset erms19
- int dos
- call serrst ; Reset port. [14]
- ret
- logo3: inc numtry ; Increment number of tries.
- mov argblk,0 ; Packet number zero.
- mov argbk1,1 ; One piece of data.
- mov bx,offset data
- mov ah,'L'
- mov [bx],ah ; Logout the remote host.
- mov ah,'G' ; Generic command packet.
- call spack
- jmp logo2 ; Tell user and die.
- nop
- call rpack5 ; Get ACK (w/o screen msgs.)
- jmp logo1 ; Go try again.
- nop
- cmp ah,'Y' ; ACK?
- jne logo4
- call serrst ; Reset port. [14]
- jmp rskp
- logo4: cmp ah,'E' ; Error packet?
- jnz logo1 ; Try sending the packet again.
- call error1
- call serrst ; Reset port. [14]
- ret
- LOGO ENDP
-
- ; FINISH - tell remote KERSRV to exit.
-
- FINISH PROC NEAR
- mov ah,cmcfm ; Parse a confirm.
- call comnd
- jmp r
- mov numtry,0 ; Initialize count.
- call serini ; Initialize port. [14]
- fin1: mov ah,numtry
- cmp ah,maxtry ; Too many times?
- js fin3 ; Nope, try it.
- fin2: mov ah,prstr
- mov dx,offset erms18
- int dos
- call serrst ; Reset port. [14]
- jmp rskp ; Go home.
- fin3: inc numtry ; Increment number of tries.
- mov argblk,0 ; Packet number zero.
- mov argbk1,1 ; One piece of data.
- mov bx,offset data
- mov ah,'F'
- mov [bx],ah ; Finish running Kermit.
- mov ah,'G' ; Generic command packet.
- call spack
- jmp fin2 ; Tell user and die.
- nop
- call rpack5 ; Get ACK (w/o screen stuff).
- jmp fin1 ; Go try again.
- nop
- cmp ah,'Y' ; Got an ACK?
- jnz fin4
- call serrst ; Reset port. [14]
- jmp rskp ; Yes, then we're done.
- fin4: cmp ah,'E' ; Error packet?
- jnz fin1 ; Try sending it again.
- call error1
- call serrst ; Reset port. [14]
- jmp rskp
- FINISH ENDP
-
- ; BYE command - tell remote KERSRV to logout & exits to DOS.
-
- BYE PROC NEAR
- mov ah,cmcfm ; Parse a confirm.
- call comnd
- jmp r
- call logo ; Tell the mainframe to logout.
- jmp rskp ; Failed - don't exit.
- mov extflg,1 ; Set exit flag.
- jmp rskp ; [8 end]
- BYE ENDP
-
- ; This is the 'exit' command. It leaves KERMIT and returns to DOS.
-
- EXIT PROC NEAR
- mov ah,cmcfm
- call comnd ; Get a confirm.
- jmp r
- mov extflg,1 ; Set the exit flag.
- jmp rskp ; Then return to system.
- EXIT ENDP
-
-
- ; This is the 'help' command. It gives a list of the commands.
-
- HELP PROC NEAR
- mov ah,cmcfm
- call comnd ; Get a confirm.
- jmp r
- mov ah,prstr ; Print a string to the console.
- mov dx,offset tophlp ; The address of the help message.
- int dos
- jmp rskp
- HELP ENDP
-
- IF ibmpc
- source db 2048 DUP(?) ; Buffer for data from port.
- srcpnt dw 0 ; Pointer in buffer (DI).
- count dw 0 ; Number of chars in int buffer.
- savesi dw 0 ; Save SI register here.
- telflg db 0 ; Are we acting as a terminal. [16] [17c]
- mst dw 0 ; Modem status address. [19b]
- mdat dw 0 ; Modem data address. [19b]
- mdeoi db 0 ; End-of-Interrupt value. [19b]
- ENDIF
-
- ; This is the CONNECT command.
-
- TELNET PROC NEAR
- mov ah,cmcfm
- call comnd ; Get a confirm.
- jmp r ; Didn't get a confirm.
- mov ah,prstr ; Output
- mov dx,offset crlf ; a crlf.
- int dos
- call dobaud ; Set baud rate. [19a]
- call domsg ; Reassure user. [19b]
- IF ibmpc
- mov ah,3 ; Get cursor position. [17b start, 20g]
- mov bh,0
- int bios
- cmp dh,24 ; Are we on row 25? [19d]
- jne nobump ; Nope, then leave where it is. [19d]
- dec dh ; Decrement ROW attribute. (DT)
- mov ah,2
- int bios ; [17b end]
- nobump: mov cs:telflg,0FFH ; Turn on Telnet flag. [16] [17c] [20g]
- call serini ; Initialize serial port. [14]
- xor ax,ax
- mov cx,ds ; Save DS in CX.
- mov ds,ax ; Use low core.
- mov bx,6CH ; "break" interrupt vector.
- push [bx]
- mov bx,6EH
- push [bx]
- mov bx,6CH
- mov ax,offset intret
- mov es,ax
- mov [bx],es ; ignore break int's (pt to "iret").
- mov bx,6EH
- mov [bx],cs
- mov ds,cx
- mov ssp,sp ; Save SP to make an easy return.
- ENDIF
- IF Z100
- mov ssp,sp ; Save current stack pointer.
- ENDIF
- telnoe: call plup ; Char at port (type to console) ?
- IF ibmpc
- cmp al,ESC
- jne telx
- jmp telesc
- ENDIF
- telx: cmp al,DEL ; Don't bother with deletes.
- je telnoe
- cmp al,XOFF ; Skip all the following too.
- je telnoe
- cmp al,XON
- je telnoe
- cmp al,00H ; Null.
- je telnoe
- IF ibmpc
- cmp al,BELL
- jne nobell
- call beep
- jmp telnoe
- nobell: cmp al,TAB ; Tab ? [15]
- jne notab ; No, skip the jump [15]
- call dotab ; Yes, handle the tab [15]
- jmp telnoe ; And get the next character [15]
- notab: call dotty ; Use our own TTY I/O. [17b]
- jmp telnoe
- ENDIF
- IF Z100
- mov dl,al ; Get the character
- mov ah,dconio ; and the function
- int dos ; type the character
- jmp telnoe ; Get next character
- ENDIF
- TELNET ENDP
-
- ; Reassure user about connection to the host. Tell him what escape
- ; sequence to use to return and the communications port and baud
- ; rate being used. [19b]
-
- DOMSG PROC NEAR
- mov ah,prstr
- mov dx,offset tmsg1
- int dos
- call escprt
- mov ah,prstr
- mov dx,offset tmsg3
- int dos
- call baudprt ; Say what baud rate we're using. [19a]
- IF ibmpc
- mov ah,prstr
- mov dx,offset tmsg4
- int dos
- mov tmp,'1' ; Assume COM1.
- cmp comflg,1
- je domsg0
- mov tmp,'2' ; Nope, we're using COM2.
- domsg0: mov dx,offset tmp
- int dos
- ENDIF
- mov ah,prstr
- mov tmp,']'
- mov dx,offset tmp
- int dos
- mov dx,offset crlf ; Output 3 CRLF's.
- int dos
- int dos
- int dos
- ret
- DOMSG ENDP
-
- ; Put character in AL to the screen. [17b start]
- IF ibmpc
- DOTTY PROC NEAR
- push ax
- mov ah,3 ;Get cursor
- mov bh,0
- int bios
- pop ax
- cmp al,8 ;Backspace?
- je dotty3
- cmp al,0DH ;CR?
- je dotty4
- cmp al,0AH ;LF?
- je dotty5
- cmp incmod,0 ;I/C?
- jne dotty7
- mov ah,9 ;Ordinary character
- mov bx,curatt
- mov cx,1
- int bios
- mov ah,2
- mov bh,0
- inc dl ;Step cursor
- cmp dl,80 ;Overflow?
- jne dotty2
- ret
- dotty1: inc dh
- dotty6: mov ah,2
- dotty2: int bios
- ret
- dotty3: dec dl ;BS
- jge dotty6
- ret
- dotty4: mov dl,0 ;CR
- jmp dotty6
- dotty5: cmp dh,23 ;LF
- jl dotty1
- mov ah,8 ;Get attribute of last line
- int bios
- mov bh,ah
- mov ax,0601H ;Scroll
- sub cx,cx
- mov dx,174FH
- jmp dotty2
- dotty7: mov temp,ax ;DK6 Save the character
- mov temp1,dx ;Save the cursor
- mov dl,78 ;Start shift at end of line
- mov temp2,dx
- mov ah,1 ;Turn off cursor
- mov ch,20H
- int bios
- dotty8: mov ah,2 ;Position to col M
- mov bh,0
- mov dx,temp2
- int bios
- mov ah,8 ;Read char/attr
- int bios
- mov cx,ax ;Save it
- mov ah,2 ;Position to col M+1
- inc dx
- int bios
- mov ah,9 ;Write char/attr
- mov al,cl
- mov bl,ch
- mov cx,1
- int bios
- dec dx
- dec temp2
- cmp dx,temp1
- jne dotty8
- mov ah,2 ;Position
- mov bh,0
- int bios
- mov ax,temp ;Write the char
- mov ah,9
- mov bx,curatt ;In the current video mode
- mov cx,1
- int bios
- mov ah,2 ;Step to next column
- inc dl
- int bios
- mov ah,1 ;Turn on cursor
- mov cx,0B0CH
- int bios
- ret ; [17b end]
- DOTTY ENDP
- ENDIF
-
- EXTLN PROC NEAR
- IF ibmpc
- call serrst ; Reset serial port. [14]
- mov sp,ssp
- xor bx,bx
- mov cx,ds ; Save DS register.
- mov ds,bx ; Address low memory.
- mov bx,6EH
- pop [bx]
- mov bx,6CH
- pop [bx]
- ; mov bx,mdmintv+2 ; Restore old interrupt vectors.
- ; pop [bx]
- ; mov bx,mdmintv
- ; pop [bx]
- mov ds,cx ; Restore DS.
- xor bx,bx
- mov cs:telflg,0 ; Not acting as terminal anymore. [16] [17c] [20g]
- ; sti
- ENDIF
- IF Z100
- mov sp,ssp
- ENDIF
- mov ah,prstr
- mov dx,offset tmsg2
- int dos
- jmp rskp
- EXTLN ENDP
-
- ;[14 start] Common initialization for using serial port.
-
- SERINI PROC NEAR
- IF ibmpc
- cli ; Disable interrupts
- cld ; Do increments in string operations
- xor ax,ax ; Address low memory
- mov es,ax
- mov bx,mdintv ; Save serial card interrupt vector. [19b]
- mov ax,es:[bx]
- mov savsci,ax
- mov ax,offset serint ; And point it to my routine
- mov es:[bx],ax
- add bx,2 ; Save CS register too. [19b]
- mov ax,es:[bx]
- mov savscs,ax
- mov es:[bx],cs
- call clrbuf ; Clear input buffer. [20e]
- mov ax,mdstat ; [19b]
- mov cs:mst,ax ; Use this address for status. [19b]
- mov ax,mddat ; [19b]
- mov cs:mdat,ax ; Use this address for data. [19b]
- mov al,mdmeoi ; [19b]
- mov cs:mdeoi,al ; Use to signify end-of-interrupt. [19b]
- in al,21H ; Set up 8259 interrupt controller
- and al,mden ; Enable INT3 or INT4. [19b]
- out 21H,al
- mov dx,mdcom ; Set up the serial card. [19b]
- mov al,3
- out dx,al
- mov dl,0F9H ; [19b]
- mov al,1 ; Set up interrupt enable register
- out dx,al
- mov dl,0FCH ; Enable interrupts from serial card
- mov al,0BH
- out dx,al
- sti ; Allow interrupts
- mov dl,0F8H
- in al,dx
- ENDIF
- ret
- SERINI ENDP
-
- SERRST PROC NEAR
- IF ibmpc
- cli ; Disable interrupts
- mov dx,03FCH ; Disable modem interrupts
- cmp comflg,1 ; Using port 1 ? [19b]
- je srst0 ; Yes - continue. [19b]
- mov dh,02 ; Set for port 2. [19b]
- srst0: mov al,3 ; [new label - 19b]
- out dx,al
- in al,21H ; Interrupt controller
- or al,mddis ; Inhibit IRQ3 or IRQ4. [19b]
- out 21H,al
- xor bx,bx ; Address low memory
- mov es,bx
- mov bx,mdintv ; Restore the serial card int vector [19b]
- mov ax,savsci
- mov es:[bx],ax
- add bx,2 ; Restore CS too. [19b]
- mov ax,savscs
- mov es:[bx],ax
- sti
- ENDIF
- ret
- SERRST ENDP ; [14 end]
-
- ; *********** serial port interrupt routine ********
-
- IF ibmpc
- SERINT PROC NEAR
- push dx
- push ax
- push es
- push di
- cld
- mov di,cs:srcpnt ; Registers for storing data.
- mov ax,cs
- mov es,ax
- mov dx,cs:mst ; Asynch status port. [19b]
- in al,dx
- test al,mdminp ; Data available?
- jz retint ; Nope.
- mov dx,cs:mdat ; [19b]
- in al,dx
- mov ah,0FFH ; Assume X-fer mode. [16 start]
- cmp cs:telflg,0 ; File transfer or terminal mode? [17c]
- jz srint0
- mov ah,7FH ; Terminal mode (7 bits only).
- srint0: and al,ah ; Fiddle with input. [16 end]
- jz retint ; Ignore nulls.
- cmp al,7FH ; Ignore rubouts, too.
- jz retint
- stosb ; Store char in buffer.
- lea ax,cs:source
- sub di,ax
- and di,7FFH ; Truncate buffer here.
- add di,ax
- inc cs:count
- retint: mov cs:srcpnt,di
- sti
- mov al,mdeoi ; [19b]
- out intcon1,al ; Send End-of-Interrupt to 8259.
- pop di
- pop es
- pop ax
- pop dx
- intret: iret
- SERINT ENDP
- ENDIF
-
- PLUP PROC NEAR
- call conchr ; Check keyboard. [15 begin]
- jmp extln ; Exit from Telnet
- nop ; In case it is a short jump (Z100)
- call prtchr ; Check serial port
- ret ; Got a character
- nop ; Use up three bytes. [15 end]
- nop
- jmp plup
- PLUP ENDP
-
- ;************************System Dependent****************************
-
- ; These I/O routines are similar to those just above.
-
- PRTCHR PROC NEAR
- IF ibmpc
- cmp cs:count,0
- jnz prtch2
- jmp rskp ; No data - check console.
- prtch2: cli ; Disable int's.
- mov cx,ds
- mov ax,cs
- mov ds,ax
- mov si,cs:savesi
- lodsb ; Get char from buffer.
- lea dx,cs:source
- sub si,dx
- and si,7FFH ; Truncate buffer after here.
- add si,dx
- dec cs:count
- mov cs:savesi,si
- mov ds,cx
- sti ; Renable int's.
- ret
- ENDIF
- IF Z100
- push bx ; Save BX
- mov ah,chr_status ; Get the function we want
- mov al,chr_sfgs ; Get the subfunction to get status
- call bios_auxfunc ; Perform the function
- cmp bl,0 ; Anything in queue?
- jne prtch1 ; Yes, go get it
- pop bx ; Restore BX
- jmp rskp ; No, give skip return
- prtch1: mov ah,chr_read ; Want to read character
- call bios_auxfunc ; Do it
- and al,07FH ; Strip off parity bit
- pop bx ; And restore BX
- ret
- ENDIF
- PRTCHR ENDP
-
-
- ; Generate a short beep.
-
- IF ibmpc
- BEEP PROC NEAR
- mov al,10110110B ; Gen a short beep (long one losses data.)
- out timer+3,al ; Code snarfed from Technical Reference.
- mov ax,533H
- out timer+2,al
- mov al,ah
- out timer+2,al
- in al,port_b
- mov ah,al
- or al,03
- out port_b,al
- sub cx,cx
- mov bl,1
- beep0: loop beep0
- dec bl
- jnz beep0
- mov al,ah
- out port_b,al
- ret
- BEEP ENDP
- ENDIF
-
- CONCHR PROC NEAR
- IF ibmpc
- mov ah,1 ; Get keyboard status.
- int keyb
- jnz cnc0x
- jmp rskp
- cnc0x: mov ah,0 ; Read a char.
- int keyb
- cmp al,0 ; Special char (cntrl-break)?
- jnz nobrk ; Nope.
- cmp ah,3 ; 3 in ah means nul code.
- jz nobrk ; Pass nulls. [14]
- cmp ah,83 ; Del Key? [14]
- je cnc1r ; Yes - send a rubout. [14]
- cmp ah,0 ; Cntrl-Break?
- jne cnc1y
- call sendbr ; Send a break. [20g]
- cnc1y: jmp rskp
- ENDIF
- IF Z100
- mov ah,dconio ; Determine if character present
- mov dl,0ffH ; Want input
- int dos ; Get status
- cmp al,00H ; Any characters there?
- jne nobrk ; if not, forget it
- jmp rskp ; Give skip return
- ENDIF
-
- cnc1r: cmp delflg,0 ; Translate BS to DEL? [19c]
- je dobs ; Nope, BS=BS [19c]
- mov al,BS ; BS (will be converted to DEL) [15]
- jmp nobrk
- dobs: mov al,07FH ; ASCII rubout. [14]
- nobrk: mov dl,al ; Store char here.
- mov ah,escchr ; Get the escape char.
- cmp ah,dl ; Is it an escape char?
- jz intchr ; If so go process it.
- cmp delflg,0 ; Translate BS to DEL? [19c]
- je dobs1 ; Nope, BS=BS [19c]
- cmp dl,BS ; Is it a backspace ? [15 begin]
- jnz cch0 ; No, check for delete
- mov dl,DEL ; Yes, get a delete
- jmp cch1 ; And send that instead
- cch0: cmp dl,DEL ; Is it a delete ?
- jnz cch1 ; No, done checking then
- mov dl,BS ; Yes, use a backspace
- cch1: mov ax,dx ; Copy character back to AX [15 end]
- dobs1: call dopar ; Set parity (if any). [10]
- mov dx,ax
- push dx
- call prtout ; Output the char to the port.
- pop dx
- mov ah,ecoflg ; Get the echo flag.
- cmp ah,0 ; Is it turned on?
- jnz cnc1x
- jmp rskp ; If not we're done here.
- cnc1x: and dl,7FH
- cmp dl,BS ; Backspace?
- je cnc2x
- cmp dl,CR ; Carriage return?
- je cnc2x
- IF ibmpc
- cmp dl,BELL
- jne cnc2y
- call beep
- jmp rskp
- ENDIF
- cnc2y: cmp dl,20H ; Is it a control char?
- jge cnc2x
- jmp rskp
- cnc2x: mov ah,dconio ; Direct console output.
- int dos ; Echo the char.
- jmp rskp
- CONCHR ENDP
-
- ; One routine to send a break for the IBM-PC and Z100. [20g]
- SENDBR PROC NEAR
- push cx
- push dx
- push ax
- xor cx,cx ; Clear loop counter.
- mov dx,mdcom ; Port address. [19b]
- in al,dx ; Get current setting.
- or al,BRKBIT ; Set send-break bit(s).
- out dx,al ; Start the break.
- pause: loop pause ; Wait a while.
- xor al,BRKBIT ; Clear send-break bit(s).
- out dx,al ; Stop the break.
- pop ax
- pop dx
- pop cx
- ret ; And return.
- SENDBR ENDP
-
- CONN PROC NEAR
- intchr: mov ah,dconio ; Direct console I/O.
- mov dl,0FFH ; Input.
- int dos ; Get a char.
- mov ah,al
- cmp ah,0 ; Is the char a null?
- jz intchr ; If so, go until we get a char.
- mov bh,ah ; Save the actual char.
- and ah,137O ; Convert to upper case.
- cmp ah,'C' ; Is it close?
- jne intch0
- ret
- intch0: cmp ah,'S' ; Is it status?
- jnz inc0x
- jmp stat01 ; If so, jump to stat01 (it will return).
- inc0x: cmp ah,'B' ; Send a break? [20g]
- jne inc1x ; No. [20g]
- call sendbr ; Yes, so send a break. [20g]
- jmp rskp ; And return. [20g]
- inc1x: mov ah,bh ; Get the char.
- cmp ah,'?' ; Is it help?
- jne intch1 ; If not, go to the next check.
- mov dx,offset inthlp ; If so, get the address of the help message.
- mov ah,prstr ; Print it.
- int dos
- jmp intchr ; Get another char.
- intch1: mov ch,ah ; Put the char into another reg.
- mov ah,escchr ; Get the escape char.
- cmp ah,ch ; Is it the escape char?
- jne intch2 ; If not, go send a beep to the user.
- mov al,ch
- call dopar ; Set parity. [10]
- intc11: mov dl,al
- call prtout ; Output it.
- jmp rskp ; Return, we are done here.
- intch2: mov dl,'G'-100O ; Otherwise send a beep.
- mov ah,dconio
- int dos
- jmp rskp
-
- ; Another similar I/O routine.
-
- ;************************System Dependent****************************
-
- prtout: mov al,dl ; Char must be in al.
- IF ibmpc
- mov dx,mddat ; [19b]
- out dx,al
- ENDIF
- IF Z100
- call bios_auxout ; Send the character
- ENDIF
- ret
- CONN ENDP
-
- ; [15 begin]
- IF ibmpc ; Only for IBM-PC's. [20g]
- DOTAB PROC NEAR
- mov ah,3 ; Read current cursor position.
- mov bh,0 ; This screen
- int bios ; From bios
- cmp dl,72 ; Are we at the last tab stop ?
- jl dotab0 ; No, move to the next
- cmp dl,79 ; Are we at the end ?
- je dotab2 ; Yes, just return
- add dl,1 ; No, move forward one position
- jmp dotab1 ; Set the cursor position
- dotab0: mov al,dl ; Get the column into al
- push dx ; Save the current cursor position
- xor ah,ah ; Zero the high end of ax
- mov bl,8 ; Get an eight
- xor bh,bh ; Zero high byte
- div bl ; Divide by 8
- mov al,ah ; Put the remainder in the low end
- xor ah,ah ; Zero the high end
- mov cl,8 ; Get an 8 into cl
- xor ch,ch ; Zero high byte
- sub cl,al ; Subtract al from cl
- xor ch,ch ; Zero high end
- pop dx ; Restore the current cursor position
- add dl,cl ; And subtract column mod 8
- dotab1: mov ah,2 ; Set cursor position
- mov bh,0 ; This screen
- int bios ; Bios call
- dotab2: ret ; Return
- DOTAB ENDP
- ENDIF ; [20g]
- ; [15 end]
-
-
- IF ibmpc ; [20g]
- TELESC PROC NEAR
- cmp vtflg,0 ; Is vt52 flag on?
- jne vt0
- jmp telnoe ; Don't do escape stuff if it's off.
- vt0: call plup
- mov ah,al ; Get the char.
- cmp ah,'Z' ; Tell host our terminal type. [20a]
- je vtiden ; [20a]
- cmp ah,'Y' ; Special char - move cursor.
- jne vt1
- jmp movcur
- vt1: cmp ah,'<' ; Start-ANSI? [17b start]
- je vtexit ; Yes, ignore
- cmp ah,'[' ; An ANSI command?
- je vtansi ; Yes, do it
- cmp ah,'@' ; Insert characters?
- jne vtnins
- mov incmod,1
- jmp telnoe
- vtnins: cmp ah,'p' ; Inverse?
- jne vtninv
- jmp vtinvi
- vtninv: cmp ah,'q' ; Normal?
- jne vtnino
- jmp vtinvo ; [17b end]
- vtnino: cmp ah,'A' ; Less than an 'A'?
- jl vtig ; Yes - ignore.
- cmp ah,'O'+1 ; Greater than 'O'? [17b]
- jns vtig ; Yes - ignore.
- mov al,'A'
- sub ah,al ; Else make into index.
- shl ah,1
- mov bx,offset ttab ; Load base addr of table.
- mov cl,ah ; Move a into cx.
- mov ch,00H ; Zero out high byte.
- add bx,cx ; Double add index+offset.
- mov bx,[bx] ; Get address of routine to call.
- jmp bx
- vtig: ; Ignore escape sequence.
- push ax ; Push the char to be output.
- mov dl,esc ; Load an escape.
- mov ah,conout ; The function code
- int dos ; and the syscal.
- pop ax ; Restore the character
- mov dl,ah ; and move to output register.
- mov ah,conout ; The function
- int dos ; and the syscall.
- ENDIF
- vtexit: jmp telnoe ; Return home. [17b]
-
- ; Used for terminal-type querying programs. [20a]
- IF ibmpc
- vtiden: mov ah,ESC ; Respond with "ESC / K".
- call outchr
- jmp telnoe ; If failed, just forget the rest.
- mov ah,"/"
- call outchr
- jmp telnoe
- mov ah,"K"
- call outchr
- jmp telnoe ; And return even if failed.
- jmp telnoe
- ENDIF
-
- ; ANSI Insert/Delete Line. [17b start, 20g]
- IF ibmpc
- vtansi: call plup
- cmp al,'?'
- je vtanso
- sub al,30H
- mov temp,ax
- call plup
- cmp al,"9"
- jg vtans1
- sub al,30H
- mov temp2,ax
- mov ax,temp
- mov dl,10
- mul dl
- add ax,temp2
- mov temp,ax
- call plup
- vtans1: cmp al,'L'
- jne vtans2
- mov ah,3 ; Get cursor position
- mov bh,0
- int bios
- mov temp1,dx
- mov cx,dx ; Do a N-line scroll
- mov cl,0
- mov dx,184FH
- mov ax,temp
- mov ah,7
- mov bh,7
- int bios
- jmp vtans3
- vtans2: cmp al,'M'
- jne vtans4
- mov ah,3
- mov bh,0
- int bios
- mov temp1,dx
- mov ax,temp
- mov ah,6
- mov cx,dx
- mov dx,184FH
- mov bh,7
- int bios
- vtans3: mov dx,temp1 ; Restore cursor position
- mov dl,0
- mov ah,2
- mov bh,0
- int bios
- vtans4: jmp telnoe
- vtanso: call plup
- call plup
- jmp telnoe
-
- vtinvi: mov curatt,0070H ; Reverse video
- jmp telnoe
- vtinvo: mov curatt,0007H ; Normal video
- jmp telnoe ; [17b end]
- TELESC ENDP
- ENDIF
-
- IF ibmpc
- TEL PROC NEAR
- movcur: call plup
- sub al,32
- mov dh,al
- mov temp,dx ; Save row position here.
- call plup
- mov dx,temp ; Restore
- sub al,32 ; Comes with 37Q added on (& starts at 1).
- mov dl,al
- mov bh,0
- mov ah,2
- int bios
- jmp telnoe
-
- curup: mov ah,3 ; Cursor up function.
- mov bh,0
- int bios
- cmp dh,0
- je cup0
- sub dh,1
- mov ah,2
- int bios
- cup0: jmp telnoe
-
- curdwn: mov ah,3 ; Cursor down.
- mov bh,0
- int bios
- cmp dh,24
- je cdn0
- add dh,1
- mov ah,2
- int bios
- cdn0: jmp telnoe
-
- currt: mov ah,3 ; Cursor right.
- mov bh,0
- int bios
- cmp dl,79
- je crt0
- add dl,1
- mov ah,2
- int bios
- crt0: jmp telnoe
-
- curlft: mov ah,3 ; Cursor left.
- mov bh,0
- int bios
- cmp dl,0
- je clt0
- sub dl,1
- mov ah,2
- int bios
- clt0: jmp telnoe
-
- curskp: jmp vtig ; Ignore for now.
-
- curclr: call locate ; Home the cursor [15]
- jmp curscr ; And clear the screen [15]
-
- curhm: call locate
- jmp telnoe
-
- curscr: mov ah,3 ; Clear to end of screen.
- mov bh,0
- int bios
- cmp dx,0
- jne csr0
- call cmblnk
- jmp telnoe
- csr0: cmp dl,0
- je csr1
- push dx
- call clreol
- pop dx
- add dh,1
- mov dl,0
- csr1: mov cx,dx
- mov dx,184FH
- mov bh,7
- ; mov al,25
- ; sub al,ch
- mov al,0
- mov ah,7
- int bios
- jmp telnoe
-
- curln: call clreol ; One routine to clear to EOL. [19a]
- jmp telnoe
-
- inslin: mov ah,3 ; Get cursor position.
- mov bh,0
- int bios
- mov temp,dx ; Save here.
- mov cx,dx
- mov cl,0 ; Start at beginning of row.
- mov dx,184FH ; End at lower corner of screen.
- mov ax,0701H
- mov bh,7
- int bios ; Scroll down one line.
- mov dx,temp ; Get back where we were.
- mov dl,0
- mov ah,2
- mov bh,0
- int bios
- jmp telnoe
-
- dellin: mov ah,3
- mov bh,0
- int bios ; Get current cursor position.
- mov temp,dx ; Remember the place.
- mov ax,0601H ; Scroll up one line.
- mov cx,dx
- mov cl,0 ; Start at beginning of row.
- mov dx,184FH
- mov bh,7
- int bios
- mov dx,temp
- mov dl,0
- mov ah,2
- mov bh,0
- int bios
- jmp telnoe
-
- ; Delete character. [17b start]
- delchr: mov ah,3 ; Get cursor position
- mov bh,0
- int bios
- mov temp,dx
- mov ah,1 ; Turn off cursor
- mov ch,20H
- int bios
- delch1: mov ah,2 ; Position to col M+1
- inc dl
- int bios
- mov ah,8 ; Get char/attr
- int bios
- mov cx,ax ; Save it
- dec dl ; Position to col M
- mov ah,2
- int bios
- mov ah,9 ; Write char/attr
- mov al,cl
- mov bl,ch
- mov cx,1
- int bios
- inc dl ; Next column
- cmp dl,79 ; About to write to col 80?
- jne delch1 ; No
- mov ah,2 ; Position to col 80
- int bios
- mov ah,9 ; Write char/attr
- mov al,' '
- int bios
- mov ah,2 ; Reset cursor
- mov dx,temp
- int bios
- mov ah,1
- mov cx,0B0CH
- int bios
- jmp telnoe
-
- ; Cancel Insert Character mode
- insmox: mov incmod,0
- jmp telnoe ; [17b end]
- TEL ENDP
-
- ; Common routine to clear to end-of-line. [19a]
- CLREOL PROC NEAR
- mov ah,3 ; Clear to end of line.
- mov bh,0
- int bios ; Get current cursor position
- mov cx,dx
- mov dl,79
- mov ah,7
- mov al,0
- mov bh,7
- int bios
- ret
- CLREOL ENDP
- ENDIF
-
-
- ; This is the SET command.
-
- SETCOM PROC NEAR
- mov dx,offset settab ; Parse a keyword from the set table.
- mov bx,offset sethlp
- mov ah,cmkey
- call comnd
- jmp r
- call bx
- jmp rskp
- SETCOM ENDP
-
-
- ; This is the ESCAPE character SET subcommand. [6 start]
-
- ESCAPE PROC NEAR
- call cmgtch ; Get a char.
- cmp ah,0
- jns es1 ; Terminator or no?
- and ah,7FH ; Turn off minus bit.
- cmp ah,'?'
- jne es0
- mov dx,offset eschlp
- mov ah,prstr
- int dos
- mov dx,offset crlf
- int dos
- mov dx,offset kerm
- int dos
- mov bx,cmdptr
- mov al,'$'
- mov [bx],al
- mov dx,offset cmdbuf
- int dos
- dec cmcptr ; Ignore dollar sign.
- dec cmccnt
- mov cmaflg,0
- jmp repars
- es0: mov ah,prstr
- mov dx,offset ermes3
- int dos
- ret
- es1: mov temp,ax
- call cmcfrm
- jmp es0
- nop ; Take up 3 bytes.
- mov ax,temp
- mov escchr,ah ; Save new value.
- ret
- ESCAPE ENDP ; [6 end]
-
- ; This is the End-of-line character SET subcommand. [5 start]
-
- EOLSET PROC NEAR
- call cmgtch ; Get the first char into AH.
- cmp ah,0
- jns eol1
- cmp ah,0BFH ; Question mark?
- je eol4
- jmp eol3
- eol1: sub ah,030H ; Digit --> real number.
- mov temp,ax ; Save the input.
- call cmcfrm
- jmp eol0 ; Got a char.
- mov ax,0
- mov bx,temp
- jmp eol2
- eol0: sub ah,030H ; Digit --> real number.
- mov temp1,ax
- call cmcfrm
- jmp eol3 ; Too many chars.
- mov bx,temp1
- mov ax,temp
- xchg al,ah
- mov ah,0
- eol2: mov temp,ax ; Save our registers.
- mov temp1,bx
- call cmcfrm
- jmp eol3
- mov bx,temp1
- mov ax,temp
- mov temp2,10 ; Get numerical value of char.
- mul temp2
- add al,bh
- mov ah,0
- cmp al,0
- jl eol3
- cmp al,1FH
- jg eol3
- mov seol,al ; Use new eol char.
- ret
- eol3: mov ah,prstr
- mov dx,offset eolerr ; Bad end-of-line char
- int dos
- jmp prserr
- eol4: mov ah,prstr
- mov dx,offset eolhlp
- int dos
- mov dx,offset crlf
- int dos
- mov dx,offset kerm
- int dos
- mov bx,cmdptr
- mov al,'$'
- mov [bx],al
- mov dx,offset cmdbuf
- int dos
- dec cmcptr ; Don't count the dollar sign.
- dec cmccnt ; Or the question mark.
- mov cmaflg,0 ; Check for more input.
- jmp repars
- EOLSET ENDP ; [5 end]
-
- ; This is the LOCAL echo SET subcommand.
-
- LCAL PROC NEAR
- mov dx,offset ontab
- mov bx,offset onhlp
- mov ah,cmkey
- call comnd
- jmp r
- push bx ; Save the parsed value.
- mov ah,cmcfm
- call comnd ; Get a confirm.
- jmp r ; Didn't get a confirm.
- pop bx
- mov ecoflg,bl ; Set the local echo flag.
- ret
- LCAL ENDP
-
- ; This is the VT52 emulation SET subcommand.
-
- IF ibmpc
- VT52EM PROC NEAR
- mov dx,offset ontab
- mov bx,offset onhlp
- mov ah,cmkey
- call comnd
- jmp r
- push bx
- mov ah,cmcfm
- call comnd ; Get a confirm.
- jmp r ; Didn't get a confirm.
- pop bx
- mov vtflg,bl ; Set the VT52 emulation flag.
- ret
- VT52EM ENDP
- ENDIF
-
- ; This is the SET subcommand to choose between COM1 and COM2. [19b]
-
- IF ibmpc
- COMSET PROC NEAR
- mov dx,offset comptab
- mov bx,offset comphlp
- mov ah,cmkey
- call comnd
- jmp r
- push bx
- mov ah,cmcfm
- call comnd ; Get a confirm.
- jmp r ; Didn't get a confirm.
- pop bx
- mov comflg,bl ; Set the comm port flag.
- call dobaud ; Set the baud rate for the port. [19a]
- cmp comflg,1 ; Using Com 1?
- jne coms0 ; Nope.
- mov mddat,MDMDAT1 ; Set COM1 defaults.
- mov mdstat,MDMSTS1
- mov mdcom,MDMCOM1
- mov mddis,MDMINTC
- mov mden,MDMINTO
- mov mdmeoi,EOICOM
- mov mdintv,MDMINTV
- ret
- coms0: mov mddat,MDMDAT2 ; Set COM2 defaults.
- mov mdstat,MDMSTS2
- mov mdcom,MDMCOM2
- mov mddis,MDINTC2
- mov mden,MDINTO2
- mov mdmeoi,EOICOM2
- mov mdintv,MDINTV2
- ret
- COMSET ENDP
- ENDIF
-
- ; This is the SET IBM command.
-
- IBMSET PROC NEAR
- mov dx,offset ontab
- mov bx,offset onhlp
- mov ah,cmkey
- call comnd
- jmp r
- push bx
- mov ah,cmcfm
- call comnd ; Get a confirm.
- jmp r ; Didn't get a confirm.
- pop bx
- mov ibmflg,bl ; Set the IBM flag.
- cmp bl,0 ; Turning on or off? [12 start]
- je ibmst1 ; If off, set parity & local echo to defaults.
- mov ah,ibmpar ; Set IBM parity.
- mov al,1 ; Set local echo on.
- jmp ibmst2
- ibmst1: mov ah,defpar ; Reset parity to default.
- mov al,0 ; Turn off local echo.
- ibmst2: mov parflg,ah ; Set parity.
- mov ecoflg,al ; And local echo. [12 end]
- xor al,01H ; 01 -> 00, 00 -> 01. [19c]
- mov delflg,al ; BS -> DEL or BS -> BS. [19c]
- ret
- IBMSET ENDP
-
- ; This is the SET File-Warning command.
-
- FILWAR PROC NEAR
- mov dx,offset ontab
- mov bx,offset onhlp
- mov ah,cmkey
- call comnd
- jmp r
- push bx
- mov ah,cmcfm
- call comnd ; Get a confirm.
- jmp r ; Didn't get a confirm.
- pop bx
- mov flwflg,bl ; Set the IBM flag.
- ret
- FILWAR ENDP
-
- ; This is the SET aborted-file command. [20d]
-
- ABFSET PROC NEAR
- mov dx,offset abftab
- mov bx,offset abfhlp
- mov ah,cmkey
- call comnd
- jmp r
- push bx
- mov ah,cmcfm
- call comnd ; Get a confirm.
- jmp r ; Didn't get a confirm.
- pop bx
- mov abfflg,bl ; Set the aborted file flag.
- ret
- ABFSET ENDP
-
- ; This is the SET Parity command. [10 start]
-
- SETPAR PROC NEAR
- mov dx,offset partab
- mov bx,offset parhlp
- mov ah,cmkey
- call comnd
- jmp r
- push bx
- mov ah,cmcfm
- call comnd ; Get a confirm.
- jmp r ; Didn't get a confirm.
- pop bx
- mov parflg,bl ; Set the parity flag.
- ret
- SETPAR ENDP ; [10 end]
-
- ; Sets debugging mode on and off.
-
- DEBST PROC NEAR
- mov dx,offset ontab
- mov bx,offset onhlp
- mov ah,cmkey
- call comnd
- jmp r
- push bx
- mov ah,cmcfm
- call comnd ; Get a confirm.
- jmp r ; Didn't get a confirm.
- pop bx
- mov debug,bl ; Set the IBM flag.
- ret
- DEBST ENDP
-
- ; Turn bell on or off. [17a start]
-
- BELLST PROC NEAR
- mov dx,offset ontab
- mov bx,offset onhlp
- mov ah,cmkey
- call comnd
- jmp r
- push bx
- mov ah,cmcfm
- call comnd
- jmp r
- pop bx
- mov belflg,bl
- ret
- BELLST ENDP ; [17a end]
-
- ; Function to set BS -> BS or BS -> DEL. [19c]
-
- BSSET PROC NEAR
- mov dx,offset BStab
- mov bx,offset BShlp
- mov ah,cmkey
- call comnd
- jmp r
- push bx
- mov ah,cmcfm
- call comnd ; Get a confirm.
- jmp r ; Didn't get a confirm.
- pop bx
- mov delflg,bl ; Set backspace/delete flag.
- ret
- BSSET ENDP
-
- ; This function sets the baud rate.
-
- BAUDST PROC NEAR
- mov dx,offset bdtab
- mov bx,offset bdhlp
- mov ah,cmkey
- call comnd
- jmp r
- push bx
- mov ah,cmcfm
- call comnd ; Get a confirm.
- jmp r ; Didn't get one.
- pop bx
- IF ibmpc
- mov baud,bx ; Set the IBM flag.
- call dobaud ; Use common code. [19a]
- ENDIF
- IF Z100
- mov baud,bl ; Remember baud rate. [20g]
- mov bx,ds ; Set up pointer to config info
- mov es,bx ; . . .
- mov bx,offset auxcnf ; . . .
- mov ah,chr_control ; Function is control
- mov al,chr_cfsu ; Subfunction is set new config
- call bios_auxfunc ; Set the configuration
- ENDIF
- ret
- BAUDST ENDP
-
- ; Only keep one copy of the code that sets the baud rate. [19a]
-
- DOBAUD PROC NEAR
- IF ibmpc
- mov dx,mdcom ; LCR -- Initialize baud rate. [19b]
- in al,dx
- mov bl,al
- or ax,80H
- out dx,al
- mov dx,mddat ; [19b]
- mov ax,baud
- out dx,al
- inc dx
- mov al,ah
- out dx,al
- mov dx,mdcom ; [19b]
- mov al,bl
- out dx,al
- ENDIF
- IF Z100
- mov bx,ds ; Set up pointer to config info
- mov es,bx ; . . .
- mov bx,offset auxcnf ; . . .
- mov ah,chr_status ; Get the function code
- mov al,chr_sfgc ; And the subfunction to get config
- call bios_auxfunc ; Get the block
- ENDIF
- ret
- DOBAUD ENDP
-
- ; This is the STATUS command.
-
- STATUS PROC NEAR
- call stat0
- jmp r
- jmp rskp
- STATUS ENDP
-
- STAT0 PROC NEAR
- mov ah,cmcfm
- call comnd ; Get a confirm.
- jmp r ; Didn't get a confirm.
- stat01: mov dx,offset locst ; Assume local echo on.
- cmp ecoflg,0 ; Is the local echo flag on?
- jnz stat1
- mov dx,offset remst ; If not say so.
- stat1: mov ah,prstr ; Print it.
- int dos
- IF ibmpc
- mov dx,offset vtemst ; Get address of the VT52 emulation string.
- cmp vtflg,0 ; Is the VT52 emulation flag on?
- jnz stat2
- mov dx,offset novtst ; If not say so.
- stat2: mov ah,prstr ; Print it.
- int dos
- mov dx,offset cm1st ; Assume we're using COM1. [19b start]
- cmp comflg,1 ; Are we?
- je stat2a ; Yup.
- mov dx,offset cm2st ; We're using COM2.
- stat2a: mov ah,prstr
- int dos ; [19b end]
- ENDIF
- mov dx,offset ibmst ; Is IBM flag on?
- cmp ibmflg,0
- jnz stat3
- mov dx,offset noibm ; Say it's not.
- stat3: mov ah,prstr
- int dos
- mov dx,offset deboff ; Assume debug mode is off.
- cmp debug,0
- je stat4
- mov dx,offset debon
- stat4: mov ah,prstr
- int dos
- mov dx,offset flwon ; Assume file-warning on.
- cmp flwflg,0
- jne stat5
- mov dx,offset flwoff
- stat5: mov ah,prstr
- int dos
- mov dx,offset pnonst ; Assume no parity. [10 start]
- cmp parflg,parnon
- je stat6
- mov dx,offset pmrkst ; Mark parity?
- cmp parflg,parmrk
- je stat6
- mov dx,offset pevnst ; Maybe it's even parity.
- cmp parflg,parevn
- je stat6
- mov dx,offset poddst ; Odd parity?
- cmp parflg,parodd
- je stat6
- mov dx,offset pspcst
- stat6: mov ah,prstr
- int dos ;[10 end]
- mov dx,offset belon ; Tell if bells ring at end. [17a start - DT]
- cmp belflg,0
- jne stat7
- mov dx,offset beloff ; No bells.
- stat7: mov ah,prstr
- int dos ; That's it. [17a end - DT]
- mov dx,offset abfdst ; Do we discard file if abort? [20d start]
- cmp abfflg,1
- je stat8
- mov dx,offset abfkst ; Keep what we received so far.
- stat8: int dos ; [20d end]
- mov dx,offset bkdel ; Is backarrow BS or DEL... [19c start]
- cmp delflg,1 ; Is it delete?
- je stat9 ; Yup.
- mov dx,offset bkbs ; It's a backspace.
- stat9: int dos ; Tell the user. [19c end]
- mov dx,offset eolst ; Tell the end-of-line char used. [5 start]
- mov ah,prstr
- int dos
- mov ah,conout
- mov dl,seol
- add dl,40H
- int dos ; [5 end]
- mov ah,prstr
- mov dx,offset escmes ; Print escape character. [6]
- int dos
- call escprt
- call baudprt ; Print the baud rate. [19a]
- mov dx,offset cmcrlf ; Get the address of a crlf.
- mov ah,prstr ; Print it.
- int dos
- jmp rskp
- STAT0 ENDP
-
- ; Print information on the baud rate. [19a]
-
- BAUDPRT PROC NEAR
- mov dx,offset b48st ; Assume 4800 baud.
- cmp baud,B4800
- jnz bdprt0
- jmp bdprt2
- bdprt0: mov dx,offset b12st
- cmp baud,B1200
- jnz bdprt1
- jmp bdprt2
- bdprt1: mov dx,offset b18st
- cmp baud,B1800
- jz bdprt2
- mov dx,offset b24st
- cmp baud,B2400
- jz bdprt2
- mov dx,offset b96st
- cmp baud,B9600
- jz bdprt2
- mov dx,offset b03st
- IF ibmpc
- jmp bdprt2
- ENDIF
- IF Z100
- cmp baud,B0300
- jz bdprt2
- mov dx,offset b04st
- cmp baud,B00455
- jz bdprt2
- mov dx,offset b05st
- cmp baud,B0050
- jz bdprt2
- mov dx,offset b07st
- cmp baud,b0075
- jz bdprt2
- mov dx,offset b11st
- cmp baud,B0110
- jz bdprt2
- mov dx,offset b13st
- cmp baud,B01345
- jz bdprt2
- mov dx,offset b15st
- cmp baud,B0150
- jz bdprt2
- mov dx,offset b06st
- cmp baud,B0600
- je bdprt2
- mov dx,offset b20st
- cmp baud,B2000
- jz bdprt2
- mov dx,offset b19st
- cmp baud,B19200
- jz bdprt2
- mov dx,offset b38st
- ENDIF
- bdprt2: mov ah,prstr
- int dos
- ret
- BAUDPRT ENDP
-
- ; Utility routines
-
- ; Jumping to this location is like retskp. It assumes the instruction
- ; after the call is a jmp addr.
-
- RSKP PROC NEAR
- pop bp
- add bp,3
- push bp
- ret
- RSKP ENDP
-
- ; Jumping here is the same as a ret.
-
- R PROC NEAR
- ret
- R ENDP
-
- ; This routine prints the number in AX on the screen. (Thanks to Jeff
- ; Damens). No longer used but keep around just in case.
-
- ;NOUT PROC NEAR
- ; push bx ; Save some stuff.
- ; push cx
- ; push dx
- ; push ax
- ; mov bh,0 ; Don't print leading zeros.
- ; and ah,0F0H ; Only want high order nibble.
- ; mov cl,4
- ; shr ah,cl
- ; call pdig ; Print the digit.
- ; pop ax ; Restore argument.
- ; and ah,0FH ; Just the low order nibble.
- ; call pdig
- ; mov ah,al
- ; and ah,0F0H ; Only want high order nibble.
- ; mov cl,4
- ; shr ah,cl
- ; call pdig ; Print the digit.
- ; mov ah,al
- ; and ah,0FH ; Just the low order nibble.
- ; mov bh,0FFH ; Make sure at least one zero is printed.
- ; call pdig
- ; pop dx ; Restore some stuff.
- ; pop cx
- ; pop bx
- ; ret
- ;NOUT ENDP
-
- ; Print the number in AX on the screen in decimal rather that hex. [19a]
-
- NOUT PROC NEAR
- push ax
- push dx
- mov temp,10 ; Divide quotient by 10.
- cwd ; Convert word to doubleword.
- div temp ; AX <-- Quo, DX <-- Rem.
- cmp ax,0 ; Are we done?
- jz nout0 ; Yes.
- call nout ; If not, then recurse.
- nout0: add dl,'0' ; Make it printable.
- mov temp,ax
- mov ah,conout
- int dos
- mov ax,temp
- pop dx
- pop ax
- ret
- NOUT ENDP
-
- ; print the digit in register AH
-
- PDIG PROC NEAR
- push ax ; Save it.
- cmp ah,0
- jne pdig2
- cmp bh,0
- jne pdig2
- pop ax
- ret
- pdig2: mov bh,0FFH ; Set the print zero flag.
- cmp ah,10 ; Do we use digits or a-f?
- jl usedig ; Digit.
- add ah,'A'-10 ; Compute digit
- jmp havdig ; and proceed.
- usedig: add ah,'0' ; Convert to digit
- havdig: mov dl,ah
- mov ah,conout
- int dos
- pop ax
- ret
- PDIG ENDP
-
-
- ; This set of routines provides a user oriented way of parsing
- ; commands. It is similar to that of the COMND JSYS in TOPS-20.
-
-
- ; This routine prints the prompt in DE and specifies the reparse
- ; address.
-
- PROMPT PROC NEAR
- pop bx ; Get the return address.
- push bx ; Put it on the stack again.
- mov cmrprs,bx ; Save as addr to go to on reparse.
- mov bx,0 ; Clear out register.
- add bx,sp ; Get the present stack pointer.
- mov cmostp,bx ; Save for later restoral.
- mov cmprmp,dx ; Save pointer to the prompt.
- mov bx,offset cmdbuf
- mov cmcptr,bx ; Initialize the command pointer.
- mov cmdptr,bx
- mov ah,0
- mov cmaflg,ah ; Zero the flags.
- mov cmccnt,ah
- mov cmsflg,0FFH
- mov ah,prstr
- mov dx,offset cmcrlf
- int dos
- mov ah,prstr ; Print the prompt.
- mov dx,cmprmp
- int dos
- ret
- PROMPT ENDP
-
- ; This address is jumped to on reparse.
-
- PARSE PROC NEAR
- repars: mov sp,cmostp ; new sp <-- old sp
- mov bx,offset cmdbuf
- mov cmdptr,bx
- mov ah,0FFH
- mov cmsflg,ah
- mov bx,cmrprs ; Get the reparse address.
- call bx ; Go there.
-
- ; This address can be jumped to on a parsing error.
-
- prserr: mov sp,cmostp ; Set new sp to old one.
- mov bx,offset cmdbuf
- mov cmcptr,bx ; Initialize the command pointer.
- mov cmdptr,bx
- mov ah,0
- mov cmaflg,ah ; Zero the flags.
- mov cmccnt,ah
- mov cmsflg,0FFH
- mov ah,prstr
- mov dx,offset cmcrlf
- int dos
- mov ah,prstr ; Print the prompt.
- mov dx,cmprmp ; Get the prompt.
- int dos
- ; Instead return to before the prompt call.
- mov bx,cmrprs
- call bx
- PARSE ENDP
-
- ; This routine parses the specified function in AH. Any additional
- ; information is in DX and BX.
- ; Returns +1 on success
- ; +4 on failure (assumes a JMP follows the call)
-
- CMND PROC NEAR
- comnd: mov cmstat,ah ; Save what we are presently parsing.
- call cminbf ; Get chars until an action or a erase char.
- mov ah,cmstat ; Restore 'ah' for upcoming checks.
- cmp ah,cmcfm ; Parse a confirm?
- jz cmcfrm ; Go get one.
- cmp ah,cmkey ; Parse a keyword?
- jnz cm1
- jmp cmkeyw ; Try and get one.
- cm1: cmp ah,cmifi ; Parse an input file spec?
- jnz cm2
- jmp cmifil ; Go get one.
- cm2: cmp ah,cmofi ; Output file spec?
- jnz cm3
- jmp cmofil ; Go get one.
- cm3: cmp ah,cmtxt ; Parse arbitrary text. [8]
- jnz cm4
- jmp cmtext
- cm4: mov ah,prstr ; Else give error.
- mov dx,offset cmer00 ; "?Unrecognized COMND call"
- int dos
- ret
-
- ; This routine gets a confirm.
-
- cmcfrm: call cmgtch ; Get a char.
- cmp ah,0 ; Is it negative (a terminator; a space or
- ; a tab will not be returned here as they
- ; will be seen as leading white space.)
- js cmcfr0
- ret ; If not, return failure.
- cmcfr0: and ah,7FH ; Turn off the minus bit.
- cmp ah,esc ; Is it an escape?
- jne cmcfr2
- mov ah,conout
- mov dl,bell ; Get a bell.
- int dos
- mov ah,0
- mov cmaflg,ah ; Turn off the action flag.
- mov bx,cmcptr ; Move the pointer to before thee scape.
- dec bx
- mov cmcptr,bx
- mov cmdptr,bx
- dec cmccnt ; Decremrnt the char count.
- jmp cmcfrm ; Try again.
- cmcfr2: cmp ah,'?' ; Curious?
- jne cmcfr3
- mov ah,prstr ; Print something useful.
- mov dx,offset cmin00
- int dos
- mov ah,prstr
- mov dx,offset cmcrlf ; Print a crlf.
- int dos
- mov ah,prstr
- mov dx,cmprmp ; Reprint the prompt.
- int dos
- mov bx,cmdptr ; Get the pointer into the buffer.
- mov ah,'$' ; Put a $ there for printing.
- mov [bx],ah
- mov bx,cmcptr
- dec bx ; Decrement & save the buffer pointer.
- mov cmcptr,bx
- mov ah,prstr
- mov dx,offset cmdbuf
- int dos
- mov ah,0 ; Turn off the action flag.
- mov cmaflg,ah
- jmp repars ; Reparse everything.
-
- cmcfr3: cmp ah,ff ; Is it a form feed?
- jne cmcfr4
- call cmblnk ; If so blank the screen.
- cmcfr4: jmp rskp
-
- ; This routine parses a keyword from the table pointed
- ; to in DX. The format of the table is as follows:
- ;
- ; addr: db n ; Where n is the # of entries in the table.
- ; db m ; M is the size of the keyword.
- ; db 'string$' ; Where string is the keyword.
- ; dw ab ; Where ab is data to be returned.
- ;
- ; The keywords must be in alphabetical order.
-
-
- cmkeyw: mov cmhlp,bx ; Save the help.
- mov cmptab,dx ; Save the beginning of keyword table.
- mov bx,dx
- mov ch,[bx] ; Get number of entries in table.
- inc bx
- mov dx,cmdptr ; Save command pointer.
- mov cmsptr,dx ; Save pointer's here.
- cmky1: cmp ch,0 ; Any commands left to check?
- jne cmky2
- ; mov ah,prstr ; [19e]
- ; mov dx,offset cmer04 ; Complain. [1] [19e]
- ; int dos ; [19e]
- ret ; Fail if not.
- cmky2: dec ch
- mov cl,0 ; Keep track of how many chars read in so far.
- call cmgtch ; Get a char.
- cmp ah,0 ; Do we have a terminator?
- jns cmky2x
- jmp cmky4 ; Negative number means we do.
- cmky2x: inc bx ; Point to first letter of keyword.
- inc cl ; Read in another char.
- mov al,[bx]
- cmp ah,'a' ; Less than a?
- jl cmky21 ; If so, don't capitalize.
- cmp ah,'z'+1 ; More than z?
- jns cmky21
- and ah,137O ; Capitalize the letter.
- cmky21: cmp ah,al
- je cmky3
- jg cmky2y
- jmp cmky41 ; Fail if ah preceeds al alphabetically.
- cmky2y: jmp cmky6 ; Not this keyword - try the next.
- cmky3: inc bx ; We match here, how 'bout next char?
- mov al,[bx]
- cmp al,'$' ; End of keyword?
- jne cmky3x
- jmp cmky7 ; Succeed.
- cmky3x: mov dl,al ; Save al's char here.
- call cmgtch
- inc cl ; Read in another char.
- mov al,dl
- cmp ah,'a'
- jl cmky31
- cmp ah,'z'+1
- jns cmky31
- and ah,137O
- cmky31: cmp ah,9BH ; Escape Recognition (escape w/minus bit on)?
- je cmky3y
- cmp ah,0BFH ; A question mark? [3]
- je cmky3y
- cmp ah,0A0H ; A space?
- je cmky3y
- cmp ah,8DH ; Carriage return?
- je cmky3y
- jmp cmky38
- cmky3y: mov cmkptr,bx ; Save bx here.
- mov cmsiz,cx ; Save size info.
- mov cmchr,ah ; Save char for latter.
- call cmambg ; See if input is ambiguous or not.
- jmp cmky32 ; Succeeded (not ambiguous).
- mov ah,cmchr
- cmp ah,9BH ; Escape?
- je cmky3z
- jmp cmky41 ; Fail.
- cmky3z: mov ah,conout ; Else, ring a bell.
- mov dl,bell
- int dos
- mov bx,cmcptr ; Move pointer to before the escape.
- dec bx
- mov cmcptr,bx
- mov cmdptr,bx
- dec cmccnt ; Decrement char count.
- mov bx,cmkptr ; Failed - pretend user never typed ....
- mov cx,cmsiz ; ... in a char.
- dec cl ; Don't count the escape.
- dec bx
- mov cmaflg,0 ; Reset the action flag.
- jmp cmky3 ; Keep checking.
- cmky32: mov cx,cmsiz ; Restore info.
- mov bx,cmkptr ; Our place in the keyword table.
- cmp cmchr,0A0H ; Space?
- je cmky35
- cmp cmchr,0BFH ; Question mark? [3]
- je cmky35
- cmp cmchr,8DH ; Carriage return?
- je cmky35
- dec cmcptr ; Pointer into buffer of input.
- mov dx,cmcptr
- cmky33: mov ah,[bx] ; Get next char in keyword.
- cmp ah,'$' ; Are we done yet?
- jz cmky34
- mov di,dx
- mov [di],ah
- inc bx
- inc dx
- inc cmccnt
- jmp cmky33
- cmky34: mov ah,' '
- mov di,dx
- mov [di],ah ; Put a blank in the buffer.
- inc dx
- mov cx,cmcptr ; Remember where we were (for printing below).
- mov cmcptr,dx ; Update our pointers.
- mov cmdptr,dx
- mov ah,'$'
- mov di,dx
- mov [di],ah ; Add '$' for printing.
- mov ah,prstr
- mov dx,cx ; Point to beginning of filled in data.
- int dos
- inc bx ; Point to address we'll need.
- mov bx,[bx]
- mov cmaflg,0 ; Turn off action flag.
- jmp rskp
-
- cmky35: inc bx
- mov ah,[bx] ; Find end of keyword.
- cmp ah,'$'
- jne cmky35
- inc bx
- mov bx,[bx] ; Address of next routine to call.
- ; mov cmaflg,0 ; Zero the action flag.
- jmp rskp
-
- cmky38: cmp ah,al
- jne cmky6 ; Go to end of keyword and try next.
- jmp cmky3
-
- cmky4: and ah,7FH ; Turn off minus bit.
- cmp ah,'?' ; Need help?
- je cmky5
- cmp ah,' ' ; Just a space - no error.
- je cmky51
- cmp ah,cr
- je cmky51
- cmp ah,tab
- je cmky51
- cmp ah,esc ; Ignore escape?
- je cmky43
- cmky41: mov ah,prstr
- mov dx,offset cmer03
- int dos
- jmp prserr ; Parse error - give up.
-
- cmky43: mov ah,conout ; Ring a bell.
- mov dl,bell
- int dos
- mov bx,cmcptr
- dec bx
- mov cmcptr,bx
- mov cmdptr,bx
- dec cmccnt ; Don't count the escape.
- mov cmaflg,0 ; Reset action flag.
- inc ch ; Account for a previous 'dec'.
- jmp cmky1 ; Start over.
-
- cmky5: mov ah,prstr
- mov dx,cmhlp ; Print the help text.
- int dos
- mov dx,offset crlf
- int dos
- mov dx,offset kerm
- int dos
- mov bx,cmdptr ; Get pointer into buffer.
- mov al,'$'
- mov [bx],al ; Add dollar sign for printing.
- mov dx,offset cmdbuf
- int dos
- dec cmcptr ; Don't keep it in the buffer.
- dec cmccnt ; Don't conut it.
- mov cmaflg,0 ; Turn off the action flag.
- jmp repars
-
- cmky51: jmp prserr
-
- cmky6: inc bx ; Find end of keyword.
- mov al,[bx]
- cmp al,'$'
- jne cmky6
- inc bx ; Beginning of next command.
- inc bx
- inc bx
- mov dx,cmsptr ; Get old cmdptr.
- mov cmdptr,dx ; Restore.
- mov cmsflg,0FFH
- jmp cmky1 ; Keep trying.
-
- cmky7: call cmgtch ; Get char.
- cmp ah,0
- js cmky71 ; Ok if a terminator.
- dec bx
- jmp cmky6 ; No match - try next keyword.
- cmky71: inc bx ; Get necessary data.
- mov bx,[bx]
- cmp ah,9BH ; An escape?
- jne cmky72
- mov ah,prstr
- mov dx,offset prsp ; Print a space.
- int dos
- mov di,cmcptr
- dec di
- mov ah,20H
- mov [di],ah ; Replace escape char with space.
- mov cmaflg,0
- mov cmsflg,0FFH ; Pretend they typed a space.
- cmky72: jmp rskp
-
- ; See if keyword is unambiguous or not from what the user has typed in.
-
- cmambg: cmp ch,0 ; Any keywords left to check?
- jne cmamb0
- ret ; If not then not ambiguous.
- cmamb0: inc bx ; Go to end of keyword ...
- mov al,[bx] ; So we can check the next one.
- cmp al,'$'
- jne cmamb0
- add bx,4 ; Point to start of next keyword.
- dec cl ; Don't count escape.
- mov dx,cmsptr ; Buffer with input typed by user.
- cmamb1: mov ah,[bx] ; Keyword char.
- mov di,dx
- mov al,[di] ; Input char.
- cmp al,'a' ; Do capitalizing.
- jl cmam11
- cmp al,'z'+1
- jns cmam11
- and al,137O
- cmam11: cmp ah,al ; Keyword bigger than input (alphabetically)?
- jle cmamb2 ; No - keep checking.
- ret ; Yes - not ambiguous.
- cmamb2: inc bx ; Advance one char.
- inc dx
- dec cl
- jnz cmamb1
- jmp rskp ; Fail - it's ambiguous.
-
- cmifil: mov bx,dx ; Get the fcb address in bx.
- mov cmfcb,bx ; Save it.
- mov ch,0 ; Initialize char count.
- mov ah,0
- mov [bx],ah ; Set the drive to default to current.
- inc bx
- mov cmfcb2,bx
- mov cl,' '
- cmifi0: mov [bx],cl ; Blank the FCB.
- inc bx
- inc ah
- cmp ah,0BH ; Twelve?
- jl cmifi0
- cmifi1: call cmgtch ; Get another char.
- cmp ah,0 ; Is it an action character.
- jns cmifi2
- and ah,7FH ; Turn off the action bit.
- cmp ah,'?' ; A question mark?
- jne cmif12
- mov al,0
- mov cmaflg,al ; Blank the action flag.
- dec cmcptr ; Decrement the buffer pointer.
- dec cmccnt ; Decrement count.
- ; jmp cmifi8 ; Treat like any other character.
- mov ah,prstr
- mov dx,offset filhlp ; Help message.
- int dos
- mov dx,offset crlf
- int dos
- mov dx,offset kerm
- int dos
- mov bx,cmdptr
- mov al,'$'
- mov [bx],al ; Put in dollar sign for printing.
- mov dx,offset cmdbuf
- int dos
- jmp repars
- cmif12: cmp ah,esc ; An escape?
- jne cmif13
- mov ah,0
- mov cmaflg,ah ; Turn off the action flag.
- mov ah,conout
- mov dl,bell
- int dos ; Ring the bell.
- mov bx,cmcptr ; Move the pointer to before the escape.
- dec bx
- mov cmcptr,bx
- mov cmdptr,bx
- dec cmccnt ; Decrement char count.
- jmp repars
- cmif13: mov ah,ch ; It must be a terminator.
- cmp ah,0 ; Test the length of the file name.
- jnz cmf3x
- jmp cmifi9 ; If zero complain.
- cmf3x: cmp ah,0DH
- js cmf3y
- jmp cmifi9 ; If too long complain.
- cmf3y: jmp rskp ; Otherwise we have succeeded.
- cmifi2: cmp ah,'.'
- jne cmifi3
- inc ch
- mov ah,ch
- cmp ah,1H ; Any chars yet?
- jnz cmf2x
- jmp cmifi9 ; No, give error.
- cmf2x: cmp ah,0AH ; Tenth char?
- js cmf2y
- jmp cmifi9 ; Past it, give an error.
- cmf2y: mov dl,9H
- mov dh,0
- mov bx,cmfcb
- add bx,dx ; Point to file type field.
- mov cmfcb2,bx
- mov ch,9H ; Say we've gotten nine.
- jmp cmifi1 ; Get the next char.
- cmifi3: cmp ah,':'
- jne cmifi4
- inc ch
- cmp ch,2H ; Is it in right place for a drive?
- je cmif3x
- jmp cmifi9 ; If not, complain.
- cmif3x: mov ch,0 ; Reset char count.
- mov bx,cmfcb2
- sub bx,1
- mov ah,[bx] ; Get the drive name.
- sub ah,'@' ; Get the drive number.
- mov cmfcb2,bx
- mov bx,cmfcb
- mov [bx],ah ; Put it in the fcb.
- jmp cmifi1
- cmifi4: cmp ah,'*'
- jne cmifi7
- mov ah,ch
- cmp ah,8H ; Is this in the name or type field?
- jz cmifi9 ; If its where the dot should be give up.
- jns cmifi5 ; Type.
- mov cl,8H ; Eight chars.
- jmp cmifi6
- cmifi5: mov cl,0CH ; Three chars.
- cmifi6: mov wldflg,0FFH ; Remember we had a wildcard.
- mov bx,cmfcb2 ; Get a pointer into the FCB.
- mov ah,'?'
- mov [bx],ah ; Put a question mark in.
- inc bx
- mov cmfcb2,bx
- inc ch
- mov ah,ch
- cmp ah,cl
- jl cmifi6 ; Go fill in another.
- jmp cmifi1 ; Get the next char.
- cmifi7: cmp ah,03DH ; Equals sign (wildcard)?
- jne cmif7x
- mov ah,'?'
- mov wldflg,0FFH ; Say we have a wildcard.
- jmp cmifi8 ; Put into FCB.
- cmif7x: cmp ah,'0'
- jl cmif8x
- cmp ah,'z'+1
- jns cmif8x
- cmp ah,'A' ; Don't capitalize non-alphabetics.
- jl cmifi8
- and ah,137O ; Capitalize.
- cmifi8: mov bx,cmfcb2 ; Get the pointer into the FCB.
- mov [bx],ah ; Put the char there.
- inc bx
- mov cmfcb2,bx
- inc ch
- jmp cmifi1
-
- cmif8x: push es
- mov cx,ds
- mov es,cx ; Scan uses ES register.
- mov di,offset spchar ; Special chars.
- mov cx,20 ; Twenty of them.
- mov al,ah ; Char is in al.
- repnz scasb ; Search string for input char.
- cmp cx,0 ; Was it there?
- pop es
- jnz cmifi8
-
- cmifi9: mov ah,prstr
- mov dx,offset cmer02
- int dos
- ret
-
- cmofil: jmp cmifil ; For now, the same as CMIFI.
-
- ; Parse arbitrary text up to a CR. Put chars into data buffer sent to
- ; the host (pointed to by BX). Return updated pointer in BX and
- ; input size in AH.
-
- cmtext: mov cmptab,bx ; Save pointer to data buffer. [8 start]
- mov cl,0 ; Init the char count.
- cmtxt1: call cmgtch ; Get a char.
- cmp ah,0 ; Terminator?
- jns cmtxt5 ; Nope, put into the buffer.
- and ah,07FH
- cmp ah,esc ; An escape?
- jne cmtxt2
- mov ah,conout
- mov dl,bell ; Ring a bell.
- int dos
- mov cmaflg,0 ; Reset action flag.
- dec cmcptr ; Move pointer to before the escape.
- dec cmdptr
- dec cmccnt ; Decrement count.
- jmp cmtxt1 ; Try again.
- cmtxt2: cmp ah,'?' ; Asking a question?
- jz cmtxt3
- cmp ah,ff ; Formfeed?
- jne cmtx2x
- call cmblnk
- cmtx2x: mov ah,cl ; Return count in AH.
- mov bx,cmptab ; Return updated pointer.
- jmp rskp
- cmtxt3: mov cmaflg,0 ; Reset action flag to zero.
- cmtxt5: inc cl ; Increment the count.
- mov bx,cmptab ; Pointer into destination array.
- mov [bx],ah ; Put char into the buffer.
- inc bx
- mov cmptab,bx
- jmp cmtxt1 ; [8 end]
-
- cminbf: push dx
- push bx
- mov cx,dx ; Save value here too.
- mov ah,cmaflg ; Is the action char flag set?
- cmp ah,0
- je cminb1
- jmp cminb9 ; If so get no more chars.
- cminb1: inc cmccnt ; Increment the char count.
- mov ah,conin ; Get a char.
- int dos
- mov ah,al ; Keep char in 'ah'.
- mov bx,cmcptr ; Get the pointer into the buffer.
- mov [bx],ah ; Put it in the buffer.
- inc bx
- mov cmcptr,bx
- cmp ah,25O ; Is it a ^U?
- jne cminb2
- cmnb12: mov ah,prstr
- mov dx,offset clrlin
- int dos
- IF ibmpc
- mov ax,0920H ; Write spaces.
- mov bx,7 ; Clear the line.
- mov cx,80
- int bios
- ENDIF
- mov ah,prstr
- mov dx,cmprmp ; Print the prompt.
- int dos
- mov bx,offset cmdbuf
- mov cmcptr,bx ; Reset the point to the start.
- mov cmccnt,0 ; Zero the count.
- mov dx,cx ; Preserve original value of dx.
- jmp repars ; Go start over.
- cminb2: cmp ah,10O ; Or backspace?
- jz cminb3
- cmp ah,del ; Delete?
- jne cminb4
- mov ah,prstr ; Print the delete string.
- mov dx,offset delstr
- int dos
- cminb3: mov ah,cmccnt ; Decrement the char count by two.
- dec ah
- dec ah
- cmp ah,0 ; Have we gone too far?
- jns cmnb32 ; If not proceed.
- mov ah,conout ; Ring the bell.
- mov dl,bell
- int dos
- jmp cmnb12 ; Go reprint prompt and reparse.
- cmnb32: mov cmccnt,ah ; Save the new char count.
- mov ah,prstr ; Erase the character.
- mov dx,offset clrspc
- int dos
- mov bx,cmcptr ; Get the pointer into the buffer.
- dec bx ; Back up in the buffer.
- dec bx
- mov cmcptr,bx
- jmp repars ; Go reparse everything.
- cminb4: cmp ah,'?' ; Is it a question mark.
- jz cminb6
- cmp ah,esc ; Is it an escape?
- jz cminb8
- cmp ah,cr ; Is it a carriage return?
- jz cminb5
- cmp ah,lf ; Is it a line feed?
- jz cminb5
- cmp ah,ff ; Is it a formfeed?
- jne cminb7
- call cmblnk
- call locate
- cminb5: mov ah,cmccnt ; Have we parsed any chars yet?
- cmp ah,1
- jnz cminb6
- jmp prserr ; If not, just start over.
- cminb6: mov ah,0FFH ; Set the action flag.
- mov cmaflg,ah
- jmp cminb9
- cminb7: jmp cminb1 ; Get another char.
-
- cminb8: mov ah,prstr ; Don't print the escape char.
- mov dx,offset escspc
- int dos
- jmp cminb6
-
- cminb9: pop bx
- pop dx
- ret
-
- cmgtch: push cx
- push bx
- push dx
- cmgtc1: mov ah,cmaflg
- cmp ah,0 ; Is it set.
- jne cmgt10
- call cminbf ; If the action char flag is not set get more.
- cmgt10: mov bx,cmdptr ; Get a pointer into the buffer.
- mov ah,[bx] ; Get the next char.
- inc bx
- mov cmdptr,bx
- cmp ah,' ' ; Is it a space?
- jz cmgtc2
- cmp ah,tab ; Or a tab?
- jne cmgtc3
- cmgtc2: mov ah,cmsflg ; Get the space flag.
- cmp ah,0 ; Was the last char a space?
- jne cmgtc1 ; Yes, get another char.
- mov ah,0FFH ; Set the space flag.
- mov cmsflg,ah
- mov ah,' '
- pop dx
- pop bx
- jmp cmgtc5
- cmgtc3: mov al,0
- mov cmsflg,al ; Zero the space flag.
- pop dx
- pop bx
- cmp ah,esc
- jz cmgtc5
- cmp ah,'?' ; Is the user curious?
- jz cmgtc4
- cmp ah,cr
- jz cmgtc4
- cmp ah,lf
- jz cmgtc4
- cmp ah,ff
- je cmgtc4
- pop cx
- ret ; Not an action char, just return.
- cmgtc4: dec cmdptr
- cmgtc5: or ah,80H ; Make the char negative to indicate
- pop cx
- ret ; it is a terminator.
- CMND ENDP
-
- ; This routine blanks the screen.
-
- CMBLNK PROC NEAR ; This is stolen from the IBM example.
- IF ibmpc
- mov cx,0
- mov dx,184FH
- mov bh,7
- mov ax,600H
- int bios
- ENDIF
- IF Z100
- mov ah,prstr ; Get the function code
- mov dx,offset clrscr ; Want to clear the screen
- int dos ; Do it
- ENDIF
- ret
- CMBLNK ENDP
-
- ; Cursor control.
-
- LOCATE PROC NEAR
- IF ibmpc
- mov dx,0 ; Go to top left corner of screen.
- mov bh,0
- mov ah,2
- int bios
- ENDIF
- IF Z100
- mov ah,prstr ; Function is print string
- mov dx,offset homcur ; Home cursor
- int dos ; do it
- ENDIF
- ret
- LOCATE ENDP
-
-
- MAIN ENDS ; End of code section.
- END START